Template Engines
Use template engines for dynamic email content with @visulima/email
Template Engines
@visulima/email supports multiple template engines for rendering dynamic email content. All template engines implement the TemplateRenderer interface and can be used with the MailMessage.view() method.
type TemplateRenderer = (
template: unknown,
data?: Record<string, unknown>,
options?: Record<string, unknown>,
) => string | Promise<string>;Available Template Engines
Handlebars
Handlebars provides logic-less templating with support for helpers and partials.
Install: npm install handlebars
import { MailMessage } from "@visulima/email";
import { renderHandlebars } from "@visulima/email/template/handlebars";
const message = new MailMessage()
.to("user@example.com")
.from("sender@example.com")
.subject("Welcome");
await message.view(renderHandlebars, "<h1>Hello {{name}}!</h1><p>Welcome to {{company}}.</p>", {
name: "John",
company: "Acme Corp",
});Registering Helpers
import { registerHandlebarsHelper } from "@visulima/email/template/handlebars";
registerHandlebarsHelper("uppercase", (str: string) => str.toUpperCase());
await message.view(renderHandlebars, "<h1>Hello {{uppercase name}}!</h1>", {
name: "John",
});Registering Partials
import { registerHandlebarsPartial } from "@visulima/email/template/handlebars";
registerHandlebarsPartial("header", "<header><h1>{{title}}</h1></header>");
await message.view(renderHandlebars, "{{> header}}<p>Content here</p>", {
title: "Welcome",
});MJML
MJML is a framework that makes it easy to create responsive emails. It compiles MJML markup to HTML.
Install: npm install mjml
import { MailMessage } from "@visulima/email";
import mjml from "@visulima/email/template/mjml";
const message = new MailMessage()
.to("user@example.com")
.from("sender@example.com")
.subject("Welcome");
const mjmlTemplate = `
<mjml>
<mj-body>
<mj-section>
<mj-column>
<mj-text>Hello World!</mj-text>
</mj-column>
</mj-section>
</mj-body>
</mjml>
`;
await message.view(mjml, mjmlTemplate);MJML Options
| Option | Type | Default | Description |
|---|---|---|---|
beautify | boolean | false | Beautify the output HTML |
minify | boolean | false | Minify the output HTML |
keepComments | boolean | true | Keep comments in the output |
validationLevel | "strict" | "soft" | "skip" | "soft" | Validation strictness level |
fonts | Record<string, string> | - | Custom fonts map |
await message.view(mjml, mjmlTemplate, {}, {
minify: true,
validationLevel: "strict",
});React Email
React Email lets you build beautiful emails using React components.
Install: npm install @react-email/render @react-email/components
import { MailMessage } from "@visulima/email";
import reactEmail from "@visulima/email/template/react-email";
import { Html, Head, Body, Text } from "@react-email/components";
const WelcomeEmail = ({ name }: { name: string }) => (
<Html>
<Head />
<Body>
<Text>Hello {name}!</Text>
</Body>
</Html>
);
const message = new MailMessage()
.to("user@example.com")
.from("sender@example.com")
.subject("Welcome");
await message.view(reactEmail, <WelcomeEmail name="John" />);React Email Options
| Option | Type | Default | Description |
|---|---|---|---|
plainText | boolean | false | Render as plain text instead of HTML |
pretty | boolean | false | Pretty print the output HTML |
Vue Email
Vue Email lets you build emails with Vue components.
Install: npm install @vue-email/render @vue-email/components
import { MailMessage } from "@visulima/email";
import vueEmail from "@visulima/email/template/vue-email";
const message = new MailMessage()
.to("user@example.com")
.from("sender@example.com")
.subject("Welcome");
await message.view(vueEmail, VueEmailComponent, {
name: "John",
company: "Acme",
});Vue Email Options
| Option | Type | Default | Description |
|---|---|---|---|
plainText | boolean | false | Render as plain text instead of HTML |
pretty | boolean | false | Pretty print the output HTML |
htmlToTextOptions | Record<string, unknown> | - | Options for HTML-to-text conversion |
HTML-to-Text
The HTML-to-text converter transforms HTML content into readable plain text. It is used automatically by MailMessage when only HTML content is provided (auto-text generation).
Install: npm install html-to-text
import htmlToText from "@visulima/email/template/html-to-text";
const text = htmlToText("<h1>Hello World</h1><p>Welcome to our platform.</p>");
// Output: "HELLO WORLD\n\nWelcome to our platform."HTML-to-Text Options
| Option | Type | Default | Description |
|---|---|---|---|
wordwrap | number | false | 80 | Word wrap limit (false to disable) |
preserveNewlines | boolean | false | Preserve newlines in output |
longWordSplit | object | - | Options for handling long words |
selectors | object[] | - | Custom selectors for formatting elements |
Auto-Generated Text Content
When you use message.view() or set HTML content with message.html(), @visulima/email automatically generates a plain text version using the HTML-to-text converter. This ensures email clients that don't support HTML still display readable content.
To disable auto-text generation:
await message.view(renderHandlebars, template, data, {
autoText: false,
});Text-Only Templates
Use viewText() for text-only template rendering:
import { renderHandlebars } from "@visulima/email/template/handlebars";
const message = new MailMessage()
.to("user@example.com")
.from("sender@example.com")
.subject("Welcome");
await message.viewText(renderHandlebars, "Hello {{name}}! Welcome to {{company}}.", {
name: "John",
company: "Acme Corp",
});Custom Template Engines
You can create custom template engines by implementing the TemplateRenderer type:
import type { TemplateRenderer } from "@visulima/email";
const myRenderer: TemplateRenderer = (template, data, options) => {
let result = template as string;
for (const [key, value] of Object.entries(data || {})) {
result = result.replaceAll(`\${${key}}`, String(value));
}
return result;
};
await message.view(myRenderer, "<h1>Hello ${name}!</h1>", {
name: "John",
});