Email Templates
Create reusable email templates with dynamic content and consistent styling.
Overview
Email templates let you create reusable layouts with dynamic content. Instead of building HTML for every email, define templates once and inject variables at send time.
Template Basics
Creating a Template
const template = await client.templates.create({
name: 'Welcome Email',
subject: 'Welcome to {{company_name}}!',
html: `
<h1>Welcome, {{user_name}}!</h1>
<p>Thanks for joining {{company_name}}.</p>
<a href="{{action_url}}">Get Started</a>
`,
});Sending with a Template
await client.emails.send({
from: 'hello@yourapp.com',
to: 'user@example.com',
templateId: template.id,
variables: {
company_name: 'Acme Inc',
user_name: 'John',
action_url: 'https://app.acme.com/onboarding',
},
});Variable Syntax
Basic Variables
Use double curly braces for variable substitution:
<p>Hello, {{first_name}}!</p>Nested Variables
Access nested object properties with dot notation:
<p>Order #{{order.id}} for {{order.customer.name}}</p>Variables:
{
"order": {
"id": "12345",
"customer": {
"name": "John Doe"
}
}
}Default Values
Provide fallback values for missing variables:
<p>Hello, {{first_name|default:"there"}}!</p>Conditional Content
If Statements
Show content conditionally:
{{#if has_subscription}}
<p>Thanks for being a subscriber!</p>
{{else}}
<p>Consider upgrading to our premium plan.</p>
{{/if}}Unless Statements
Show content when condition is false:
{{#unless is_verified}}
<p>Please verify your email address.</p>
{{/unless}}Loops
Each Loops
Iterate over arrays:
<h2>Your Order</h2>
<ul>
{{#each items}}
<li>{{this.name}} - ${{this.price}}</li>
{{/each}}
</ul>Variables:
{
"items": [
{ "name": "Widget", "price": "9.99" },
{ "name": "Gadget", "price": "19.99" }
]
}Template Best Practices
Keep Templates Simple
- Avoid complex logic in templates
- Calculate values in your application code
- Pass pre-formatted data to templates
Use Meaningful Variable Names
<!-- Good -->
<p>Your order {{order_number}} has shipped.</p>
<!-- Bad -->
<p>Your order {{x}} has shipped.</p>Test with Sample Data
Always test templates with realistic data before production use.
Handle Missing Variables
Use default values to prevent blank content:
<p>Hello, {{first_name|default:"Valued Customer"}}!</p>Template Layouts
Base Layout
Create a base layout for consistent styling:
<!-- layouts/base.html -->
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
.container { max-width: 600px; margin: 0 auto; }
.button { background: #007bff; color: white; padding: 12px 24px; }
</style>
</head>
<body>
<div class="container">
{{content}}
<footer>
<p>© {{year}} {{company_name}}</p>
</footer>
</div>
</body>
</html>Content Templates
Create content that extends the base:
<h1>Order Confirmation</h1>
<p>Thanks for your order, {{customer_name}}!</p>
<table>
{{#each items}}
<tr>
<td>{{this.name}}</td>
<td>${{this.price}}</td>
</tr>
{{/each}}
</table>
<p>Total: ${{total}}</p>Managing Templates
Versioning
Templates maintain version history:
// Get template versions
const versions = await client.templates.listVersions(templateId);
// Revert to previous version
await client.templates.revertToVersion(templateId, versionId);Testing Templates
Preview templates with test data:
const preview = await client.templates.preview(templateId, {
variables: {
first_name: 'Test User',
order_number: '12345',
},
});
console.log(preview.html);Next Steps
- Sending Emails - Send emails with templates
- Tracking - Track opens and clicks
- API Reference - Template API documentation
On This Page
- Overview
- Template Basics
- Creating a Template
- Sending with a Template
- Variable Syntax
- Basic Variables
- Nested Variables
- Default Values
- Conditional Content
- If Statements
- Unless Statements
- Loops
- Each Loops
- Template Best Practices
- Keep Templates Simple
- Use Meaningful Variable Names
- Test with Sample Data
- Handle Missing Variables
- Template Layouts
- Base Layout
- Content Templates
- Managing Templates
- Versioning
- Testing Templates
- Next Steps