Template Components
A comprehensive guide to all available components in email and attachment templates.
Table of Contents
- Overview
- Component Categories
- Template Type Support
- Layout Components
- Content Components
- Data Components
- Interactive Components
- Advanced Components
- Best Practices
- Complete Examples
Overview
Templates are built using a component-based architecture. Each component represents a visual or functional element in your email or attachment. Components can be simple (like text or images) or complex (like tables with calculations or conditional sections).
Key Concepts
Component Structure: Every component has:
id(string, required): Unique identifiertype(string, required): Component type (e.g., “text”, “button”, “table”)props(object, optional): Component properties and configurationchildren(array, optional): Nested child componentscontent(string, optional): Text content for some components
Template Types: Components can be used in:
- Email templates: Rendered as HTML emails
- Attachment templates: Rendered as PDF or Excel files
- Both: Works in both template types
Variable Support: Most components support Handlebars syntax {{variableName}} for dynamic content.
Component Categories
Layout Components
Structure and organize other components:
- Container - Wrapper with background, padding, and styling
- Columns - Multi-column layouts (2-4 columns)
- Table Layout - Grid-based layout system
- Divider - Horizontal separator line
- Spacer - Vertical spacing control
Content Components
Display text, images, and static content:
- Text - Simple paragraph text
- Heading - Headings (H1-H6)
- Rich Text - Formatted HTML content
- Image - Images with responsive sizing
- List - Ordered and unordered lists
- HTML Fragment - Custom HTML with CSS
Data Components
Display and manipulate data:
- Table - Data tables with 5 column types
- Chart - Visualizations (email + attachment)
- Loop - Repeat content for arrays
- Conditional - Show/hide based on conditions
Interactive Components
Email-specific interactive elements:
- Button - Call-to-action buttons
- QR Code - QR codes for tickets, URLs, etc.
- Timeline - Status progression timeline
Template Type Support
| Component | Attachment | Notes | |
|---|---|---|---|
| Text | ✅ | ✅ | Basic text component |
| Heading | ✅ | ✅ | H1-H6 headings |
| Rich Text | ✅ | ✅ | Advanced formatting |
| Button | ✅ | ❌ | Email only (clickable links) |
| Image | ✅ | ✅ | Responsive images |
| Container | ✅ | ✅ | Layout wrapper |
| Columns | ✅ | ✅ | Multi-column layouts |
| List | ✅ | ✅ | Ordered/unordered lists |
| Table | ✅ | ✅ | Data tables |
| Table Layout | ✅ | ✅ | Grid layout |
| Divider | ✅ | ✅ | Horizontal line |
| Spacer | ✅ | ✅ | Vertical spacing |
| Chart | ✅ | ✅ | Data visualizations (images in emails, native in PDFs/Excel) |
| Loop | ✅ | ✅ | Iterate over arrays |
| Conditional | ✅ | ✅ | Conditional rendering |
| QR Code | ✅ | ❌ | Email only (scannable codes) |
| Timeline | ✅ | ❌ | Email only (status progression) |
| HTML Fragment | ✅ | ✅ | Custom HTML/CSS |
Layout Components
Container
Wrapper component with background, padding, and styling. Use to group and style related content.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
backgroundColor | string | No | transparent | Background color (hex, rgb, rgba, named) |
padding | string | No | ”0px” | CSS padding value (e.g., “20px”, “10px 20px”) |
maxWidth | string | No | none | Maximum width (e.g., “600px”, “100%“) |
borderRadius | string | No | ”0px” | Border radius (e.g., “8px”, “50%“) |
border | string | No | none | CSS border value (e.g., “1px solid #000”) |
align | enum | No | left | Alignment: “left”, “center”, “right” |
margin | string | No | ”0px” | CSS margin value |
children | array | No | [] | Child components |
Example
{
"type": "container",
"id": "welcome-section",
"props": {
"backgroundColor": "#f8f9fa",
"padding": "40px 20px",
"maxWidth": "600px",
"borderRadius": "8px",
"align": "center"
},
"children": [
{
"type": "heading",
"id": "welcome-heading",
"props": { "level": 1 },
"content": "Welcome {{userName}}!",
"style": { "textAlign": "center" }
},
{
"type": "text",
"id": "welcome-text",
"content": "Thanks for joining us. Your account is ready.",
"style": { "textAlign": "center" }
}
]
}Use Cases
- Group related content with consistent styling
- Create card-like sections in emails
- Add background colors to highlight sections
- Control maximum width for better readability
Columns
Multi-column layout component for side-by-side content (2-4 columns).
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
columnCount | number | No | 2 | Number of columns (1-4) |
gap | string/number | No | ”20px” | Gap between columns |
columnWidths | array | No | equal | Array of width values (e.g., [“50%”, “50%”]) |
backgroundColor | string | No | transparent | Background color |
padding | string | No | ”0px” | CSS padding value |
verticalAlign | enum | No | top | Alignment: “top”, “middle”, “bottom” |
stackOnMobile | boolean | No | true | Stack columns on small screens |
children | array | No | [] | Child components (one per column) |
Example
{
"type": "columns",
"id": "feature-columns",
"props": {
"columnCount": 3,
"gap": "20px",
"stackOnMobile": true
},
"children": [
{
"type": "container",
"id": "feature-1",
"props": { "padding": "20px", "align": "center" },
"children": [
{
"type": "image",
"id": "icon-1",
"props": {
"source": "https://example.com/icon1.png",
"width": 64,
"height": 64,
"alignment": "center"
}
},
{
"type": "heading",
"id": "title-1",
"props": { "level": 3 },
"content": "Fast Delivery",
"style": { "textAlign": "center" }
},
{
"type": "text",
"id": "desc-1",
"content": "Same-day shipping available",
"style": { "textAlign": "center" }
}
]
},
{
"type": "container",
"id": "feature-2",
"props": { "padding": "20px", "align": "center" },
"children": [
{
"type": "image",
"id": "icon-2",
"props": {
"source": "https://example.com/icon2.png",
"width": 64,
"height": 64,
"alignment": "center"
}
},
{
"type": "heading",
"id": "title-2",
"props": { "level": 3 },
"content": "Secure Payment",
"style": { "textAlign": "center" }
},
{
"type": "text",
"id": "desc-2",
"content": "SSL encrypted checkout",
"style": { "textAlign": "center" }
}
]
},
{
"type": "container",
"id": "feature-3",
"props": { "padding": "20px", "align": "center" },
"children": [
{
"type": "image",
"id": "icon-3",
"props": {
"source": "https://example.com/icon3.png",
"width": 64,
"height": 64,
"alignment": "center"
}
},
{
"type": "heading",
"id": "title-3",
"props": { "level": 3 },
"content": "24/7 Support",
"style": { "textAlign": "center" }
},
{
"type": "text",
"id": "desc-3",
"content": "Always here to help",
"style": { "textAlign": "center" }
}
]
}
]
}Use Cases
- Feature lists with icons
- Side-by-side product comparisons
- Contact information with labels and values
- Multi-column layouts in newsletters
Table Layout
Grid-based layout component (different from data tables). Creates a fixed grid for positioning components.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
rows | number | No | 1 | Number of rows (1-20) |
cols | number | No | 1 | Number of columns (1-10) |
borderWidth | string | No | ”0px” | Border width (e.g., “1px”) |
borderColor | string | No | #000000 | Border color |
cellPadding | string | No | ”0px” | CSS padding for each cell |
cellBackgroundColor | string | No | transparent | Background color for cells |
cellAlign | enum | No | left | Cell alignment: “left”, “center”, “right” |
cellVerticalAlign | enum | No | top | Vertical alignment: “top”, “middle”, “bottom” |
borderCollapse | boolean | No | true | Collapse borders between cells |
width | string | No | 100% | Table width |
children | array | No | [] | Child components (one per cell) |
Example
{
"type": "table-layout",
"id": "info-grid",
"props": {
"rows": 2,
"cols": 2,
"borderWidth": "1px",
"borderColor": "#e0e0e0",
"cellPadding": "10px",
"width": "100%"
},
"children": [
{
"type": "text",
"id": "label-1",
"content": "Order Number:",
"style": { "fontWeight": "bold" }
},
{
"type": "text",
"id": "value-1",
"content": "{{orderNumber}}"
},
{
"type": "text",
"id": "label-2",
"content": "Order Date:",
"style": { "fontWeight": "bold" }
},
{
"type": "text",
"id": "value-2",
"content": "{{orderDate}}"
}
]
}Use Cases
- Form-like layouts (label + value pairs)
- Invoice headers with structured data
- Fixed grid positioning for components
- Simple data displays without table headers
Divider
Horizontal separator line for visual separation.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
style | enum | No | solid | Line style: “solid”, “dashed”, “dotted” |
thickness | number | No | 1 | Line thickness in pixels (1-10) |
color | string | No | #e0e0e0 | Line color |
width | string | No | 100% | Divider width (e.g., “80%”, “600px”) |
margin | string | No | 20px 0 | CSS margin value |
Example
{
"type": "divider",
"id": "section-divider",
"props": {
"style": "solid",
"thickness": 2,
"color": "#cccccc",
"width": "80%",
"margin": "30px 0"
}
}Use Cases
- Separate sections in emails
- Visual breaks between content blocks
- Footer separators
- Section headers
Spacer
Vertical spacing component for controlling whitespace.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
height | string/number | No | 20px | Vertical spacing (e.g., “40px”, 60) |
Example
{
"type": "spacer",
"id": "section-spacing",
"props": {
"height": "40px"
}
}Use Cases
- Add vertical spacing between sections
- Control whitespace in layouts
- Improve readability with breathing room
- Consistent spacing throughout template
Content Components
Text
Simple paragraph text component for body content.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
content | string | Yes | - | Text content (supports {{variables}}) |
style | object | No | - | Styling options |
style.fontSize | number | No | 16 | Font size (6-72) |
style.fontWeight | string/number | No | normal | Weight: “normal”, “bold”, “bolder”, “lighter”, 100-900 |
style.color | string | No | #000000 | Text color |
style.backgroundColor | string | No | transparent | Background color |
style.textAlign | enum | No | left | Alignment: “left”, “center”, “right”, “justify” |
style.lineHeight | string/number | No | 1.5 | Line height |
position | object | No | - | Position in attachment (x, y coordinates) |
Example
{
"type": "text",
"id": "intro-text",
"content": "Hello {{userName}}, your order #{{orderNumber}} has been confirmed!",
"style": {
"fontSize": 16,
"color": "#333333",
"textAlign": "left",
"lineHeight": 1.6
}
}Use Cases
- Body paragraphs
- Descriptions
- Explanatory text
- Dynamic content with variables
Heading
Heading component for section titles (H1-H6).
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
content | string | Yes | - | Heading text (supports {{variables}}) |
level | number | Yes | 1 | Heading level (1-6) |
style | object | No | - | Styling options (same as Text) |
position | object | No | - | Position in attachment (x, y coordinates) |
Example
{
"type": "heading",
"id": "page-title",
"props": {
"level": 1
},
"content": "Order Confirmation",
"style": {
"fontSize": 32,
"fontWeight": "bold",
"color": "#007bff",
"textAlign": "center"
}
}Use Cases
- Page titles
- Section headings
- Email subject-like headings
- Hierarchical content structure
Rich Text
Enhanced text component with HTML formatting support.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
content | string | No | "" | HTML content |
props | object | No | - | Styling options |
props.align | enum | No | left | Alignment: “left”, “center”, “right”, “justify” |
props.color | string | No | #000000 | Text color |
props.backgroundColor | string | No | transparent | Background color |
props.fontSize | string/number | No | 16px | Font size (8-72 or CSS value) |
props.lineHeight | string/number | No | 1.5 | Line height |
props.padding | string | No | 0px | CSS padding value |
props.maxWidth | string | No | none | Maximum width |
Example
{
"type": "rich-text",
"id": "formatted-content",
"content": "<p>Your order includes:</p><ul><li><strong>Premium Plan</strong> - $99/month</li><li>24/7 Support</li><li>Unlimited API calls</li></ul>",
"props": {
"align": "left",
"fontSize": "16px",
"padding": "20px"
}
}Use Cases
- Complex formatted content
- Lists with formatting
- Mixed content (bold, italic, links)
- Pre-formatted HTML sections
Image
Responsive image component for displaying images.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
source | string | Yes | - | Image URL or data URI (supports {{variables}}) |
alt | string | No | "" | Alt text for accessibility |
width | number/string | No | auto | Image width (pixels or CSS value, max 2000) |
height | number/string | No | auto | Image height (pixels or CSS value, max 2000) |
alignment | enum | No | left | Alignment (email): “left”, “center”, “right” |
position | object | No | - | Position (attachment): x and y coordinates |
style | object | No | - | Additional styling |
Example
{
"type": "image",
"id": "product-image",
"props": {
"source": "{{productImageUrl}}",
"alt": "{{productName}}",
"width": 400,
"height": 300,
"alignment": "center"
}
}Use Cases
- Product images
- Logos and branding
- Illustrations
- User avatars
- Dynamic images from variables
List
Ordered or unordered list component.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
items | array | No | [] | Array of list items (strings, max 100) |
ordered | boolean | No | false | True for ordered list, false for unordered |
listStyleType | enum | No | disc/decimal | List style: “disc”, “circle”, “square” (unordered), “decimal”, “lower-alpha”, etc. (ordered) |
color | string | No | #000000 | Text color |
backgroundColor | string | No | transparent | Background color |
fontSize | string/number | No | 16px | Font size (8-72 or CSS value) |
lineHeight | string/number | No | 1.5 | Line height (0.5-3) |
padding | string | No | 0px | CSS padding value |
margin | string | No | 0px | CSS margin value |
itemSpacing | string/number | No | 8px | Spacing between items (0-50) |
indent | string/number | No | 20px | List indentation (0-100) |
Example
{
"type": "list",
"id": "feature-list",
"props": {
"ordered": false,
"listStyleType": "disc",
"items": [
"Free shipping on all orders",
"30-day money-back guarantee",
"24/7 customer support",
"Lifetime warranty"
],
"color": "#333333",
"fontSize": 16,
"itemSpacing": "12px"
}
}Use Cases
- Feature lists
- Benefit lists
- Instructions or steps
- Table of contents
- Bullet points
HTML Fragment
Custom HTML component with inline CSS for advanced layouts.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
html | string | Yes | - | Raw HTML content (max 100KB) |
css | string | No | "" | Inline CSS styles (max 50KB) |
name | string | No | "" | Optional fragment name/description (max 100 chars) |
Security Features
The HTML Fragment component includes automatic sanitization to prevent security issues:
Allowed HTML Elements:
- Layout:
div,span,section,article,header,footer,main,aside,nav - Text:
p,h1-h6,strong,em,b,i,u,small,mark,del,ins,sub,sup - Lists:
ul,ol,li,dl,dt,dd - Tables:
table,thead,tbody,tfoot,tr,th,td,caption - Links:
a(with href validation) - Media:
img(with src validation),figure,figcaption - Code:
code,pre,kbd,samp,var - Other:
br,hr,blockquote,abbr,address,time
Forbidden Patterns:
- Script tags:
<script>,javascript:,onerror=,onclick=, etc. - Dangerous CSS:
expression(),behavior:,-moz-binding:,@import url() - Executable content:
<object>,<embed>,<iframe>,<applet> - Form elements:
<form>,<input>,<button>, etc.
Variable Support: HTML fragments can contain {{variable}} syntax. Sanitization occurs after variable substitution.
Example
{
"type": "html-fragment",
"id": "custom-banner",
"props": {
"name": "Hero Banner",
"html": "<div class=\"hero\"><div class=\"hero-content\"><h1>Welcome {{userName}}</h1><p class=\"subtitle\">{{companyName}} - Building the Future</p></div></div>",
"css": ".hero { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 60px 20px; text-align: center; border-radius: 8px; } .hero-content h1 { color: white; font-size: 36px; margin: 0 0 10px 0; } .hero-content .subtitle { color: rgba(255,255,255,0.9); font-size: 18px; margin: 0; }"
}
}Use Cases
- Custom banners and hero sections
- Complex layouts not achievable with standard components
- Brand-specific designs
- Legacy HTML content migration
- Advanced styling requirements
Data Components
Table
Powerful data table component with 5 column types. See the Variables & Dynamic Content guide for complete details.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
dataSource | string | Yes | - | Variable name containing array data |
columns | array | Yes | - | Array of column definitions |
showHeader | boolean | No | true | Show table header row |
showBorder | boolean | No | true | Show table borders |
showTotalsRow | boolean | No | false | Show totals row (attachment only) |
style | object | No | - | Table styling options |
Column Types
1. Simple Field Column: Display a field directly from data
{
"header": "Product Name",
"field": "name",
"width": "40%",
"align": "left"
}2. Calculated Column: JavaScript expression calculated per row
{
"header": "Total",
"isCalculated": true,
"expression": "quantity * unitPrice",
"format": {
"type": "number",
"preset": "CURRENCY",
"currency": "USD",
"decimals": 2
}
}3. Calculated Column: JavaScript expressions for computed values
{
"header": "Total",
"isCalculated": true,
"expression": "row.quantity * row.unitPrice",
"format": {
"type": "number",
"preset": "CURRENCY",
"currency": "USD"
}
}4. Component-Based Column: Render components in cells (email only)
{
"header": "Actions",
"renderType": "component",
"component": {
"type": "button",
"props": {
"text": "View",
"url": "https://example.com/products/{{id}}"
},
"contentField": "id"
}
}Example - Order Items Table
{
"type": "table",
"id": "order-items",
"props": {
"dataSource": "{{orderItems}}",
"showHeader": true,
"showBorder": true,
"columns": [
{
"header": "Item",
"field": "name",
"width": "40%",
"align": "left"
},
{
"header": "Qty",
"field": "quantity",
"width": "15%",
"align": "center",
"format": {
"type": "number",
"preset": "DECIMAL",
"decimals": 0
}
},
{
"header": "Price",
"field": "unitPrice",
"width": "20%",
"align": "right",
"format": {
"type": "number",
"preset": "CURRENCY",
"currency": "USD",
"decimals": 2
}
},
{
"header": "Total",
"isCalculated": true,
"expression": "quantity * unitPrice",
"width": "25%",
"align": "right",
"format": {
"type": "number",
"preset": "CURRENCY",
"currency": "USD",
"decimals": 2
}
}
],
"style": {
"headerBackgroundColor": "#f8f9fa",
"headerTextColor": "#333333",
"rowBackgroundColor": "#ffffff",
"alternateRowColor": "#f8f9fa",
"borderColor": "#dee2e6"
}
}
}Totals Row (Attachment Only)
For Excel and PDF attachments, you can add a totals row with aggregation formulas:
{
"type": "table",
"id": "sales-report",
"props": {
"dataSource": "{{salesData}}",
"showTotalsRow": true,
"totalsConfig": {
"label": "Total",
"labelColumn": "product",
"aggregations": {
"quantity": "SUM",
"revenue": "SUM",
"profit": "SUM"
}
},
"columns": [
{ "header": "Product", "field": "product" },
{ "header": "Quantity", "field": "quantity" },
{ "header": "Revenue", "field": "revenue" },
{ "header": "Profit", "field": "profit" }
]
}
}Supported Aggregations: SUM, AVERAGE, COUNT, MIN, MAX
Use Cases
- Order summaries
- Invoice line items
- Product catalogs
- Price lists
- Sales reports
- Inventory lists
Chart
Data visualization component for creating charts (bar, line, pie, doughnut, area, scatter).
Template Support: Both email and attachment templates
- Emails: Charts are rendered as static images via QuickCharts API (high resolution, transparent backgrounds)
- Attachments (PDF/Excel): Charts are rendered natively with full interactivity in Excel
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
chartType | enum | Yes | - | Chart type: “bar”, “line”, “pie”, “doughnut”, “area”, “scatter” |
dataSource | string | Yes | - | Variable name containing chart data |
xAxis | string | Yes | - | Field name for X-axis |
yAxis | string | Yes | - | Field name for Y-axis |
title | string | No | "" | Chart title |
width | number | No | 600 | Chart width in pixels |
height | number | No | 400 | Chart height in pixels |
position | object | No | - | Position in attachment: x and y coordinates |
style | object | No | - | Chart styling options |
legend | object | No | - | Legend configuration |
xAxisLabel | string | No | "" | X-axis label |
yAxisLabel | string | No | "" | Y-axis label |
pdfRendering | enum | No | image | PDF rendering: “image”, “vector” |
excelRendering | enum | No | native | Excel rendering: “native”, “image” |
Chart Styles
{
"style": {
"colors": ["#007bff", "#28a745", "#ffc107", "#dc3545", "#6f42c1"],
"showLegend": true,
"showGridLines": true,
"backgroundColor": "#ffffff",
"borderColor": "#dee2e6"
}
}Legend Configuration
{
"legend": {
"show": true,
"position": "bottom"
}
}Position Options: “top”, “bottom”, “left”, “right”
Email-Specific Rendering
How it works in emails:
- Charts are converted to static PNG images via QuickCharts API
- High resolution (2x pixel ratio) for crisp display
- Transparent backgrounds blend with email design
- Email-safe fonts (Arial, Helvetica) for maximum compatibility
- No JavaScript required - works in all email clients
Recommended sizing for emails:
- Width: 600px or less (fits standard email width)
- Height: 300-400px (optimal readability)
Example - Sales Chart (Email + Attachment)
{
"type": "chart",
"id": "monthly-sales",
"props": {
"chartType": "bar",
"dataSource": "{{monthlySales}}",
"xAxis": "month",
"yAxis": "revenue",
"title": "Monthly Sales Performance",
"width": 600,
"height": 400,
"xAxisLabel": "Month",
"yAxisLabel": "Revenue ($)",
"style": {
"colors": ["#007bff"],
"showLegend": false,
"showGridLines": true,
"backgroundColor": "transparent"
}
}
}Example - Pie Chart
{
"type": "chart",
"id": "revenue-breakdown",
"props": {
"chartType": "pie",
"dataSource": "{{revenueByCategory}}",
"xAxis": "category",
"yAxis": "amount",
"title": "Revenue by Category",
"width": 600,
"height": 400,
"legend": {
"show": true,
"position": "right"
},
"style": {
"colors": ["#007bff", "#28a745", "#ffc107", "#dc3545", "#6f42c1", "#17a2b8"]
}
}
}Chart Type Guide
Bar Chart: Compare values across categories
- Use for: Sales by product, revenue by region, etc.
- Best for: Comparing discrete categories
Line Chart: Show trends over time
- Use for: Monthly sales, growth trends, etc.
- Best for: Time-series data
Pie Chart: Show proportions of a whole
- Use for: Market share, revenue breakdown, etc.
- Best for: Percentage distributions (5-7 categories max)
Doughnut Chart: Similar to pie, with center hole
- Use for: Same as pie chart, with modern aesthetic
- Best for: Highlighting a key metric in the center
Area Chart: Show cumulative trends
- Use for: Cumulative revenue, stacked categories
- Best for: Volume and trends combined
Scatter Chart: Show correlation between variables
- Use for: Price vs. quantity, correlation analysis
- Best for: Identifying relationships in data
Attachment-Specific Properties
For PDF and Excel attachments, additional rendering options are available:
{
"pdfRendering": "vector", // "vector" or "image" (vector is higher quality)
"excelRendering": "native", // "native" or "image" (native creates Excel charts)
"position": { // Absolute positioning (attachments only)
"x": 50,
"y": 100
}
}Use Cases
Email Templates:
- Weekly performance summaries
- Marketing campaign results
- Monthly sales reports
- Customer engagement metrics
- Newsletter analytics
Attachment Templates:
- Quarterly financial reports
- Sales performance dashboards
- Annual business reviews
- Analytics reports with drill-down
- KPI dashboards
Loop
Repeat content for each item in an array variable.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
dataSource | string | Yes | - | Variable name containing array data |
itemVariable | string | Yes | - | Variable name for each item (must be valid JS identifier) |
indexVar | string | No | ”index” | Variable name for index (must be valid JS identifier) |
children | array | No | [] | Components to repeat for each item |
Valid Nested Components
In Email Templates:
- text, heading, button, image, table, table-layout, divider, spacer, columns
In Attachment Templates:
- text, heading, image, table, table-layout, divider, spacer, chart, columns
Not Allowed: Loop and Conditional components cannot be nested inside loops.
Example - Product List
{
"type": "loop",
"id": "product-loop",
"props": {
"dataSource": "{{products}}",
"itemVariable": "product",
"indexVar": "i"
},
"children": [
{
"type": "container",
"id": "product-card-{{i}}",
"props": {
"padding": "20px",
"margin": "10px 0",
"backgroundColor": "#f8f9fa",
"borderRadius": "8px"
},
"children": [
{
"type": "heading",
"id": "product-name-{{i}}",
"props": { "level": 3 },
"content": "{{product.name}}"
},
{
"type": "text",
"id": "product-desc-{{i}}",
"content": "{{product.description}}",
"style": { "color": "#666666" }
},
{
"type": "text",
"id": "product-price-{{i}}",
"content": "Price: ${{product.price}}",
"style": { "fontSize": 18, "fontWeight": "bold", "color": "#007bff" }
},
{
"type": "button",
"id": "view-button-{{i}}",
"props": {
"text": "View Details",
"href": "https://example.com/products/{{product.id}}",
"backgroundColor": "#007bff",
"color": "#ffffff"
}
}
]
},
{
"type": "divider",
"id": "divider-{{i}}",
"props": {
"style": "solid",
"thickness": 1,
"color": "#e0e0e0",
"margin": "10px 0"
}
}
]
}Example - Order Items Loop
{
"type": "loop",
"id": "order-items-loop",
"props": {
"dataSource": "{{orderItems}}",
"itemVariable": "item"
},
"children": [
{
"type": "columns",
"id": "item-row",
"props": {
"columnCount": 3,
"gap": "10px"
},
"children": [
{
"type": "text",
"id": "item-name",
"content": "{{item.name}}"
},
{
"type": "text",
"id": "item-qty",
"content": "Qty: {{item.quantity}}",
"style": { "textAlign": "center" }
},
{
"type": "text",
"id": "item-total",
"content": "${{item.total}}",
"style": { "textAlign": "right", "fontWeight": "bold" }
}
]
}
]
}Use Cases
- Product lists
- Order item listings
- Team member profiles
- Event schedules
- FAQ lists
- Blog post summaries
Conditional
Show or hide content based on a condition.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
condition | string | Yes | - | JavaScript boolean expression |
children | array | No | [] | Components to show if condition is true |
Valid Nested Components
In Email Templates:
- text, heading, button, image, table, table-layout, divider, spacer, columns, container
In Attachment Templates:
- text, heading, image, table, table-layout, divider, spacer, chart, columns, container
Not Allowed: Conditional and Loop components cannot be nested inside conditionals.
Condition Syntax
Conditions are JavaScript boolean expressions evaluated at render time:
Comparison Operators:
===,!==,>,>=,<,<=
Logical Operators:
&&(AND),||(OR),!(NOT)
Examples:
"isPremium === true"
"orderTotal > 100"
"quantity >= 10 && status === 'active'"
"!isExpired"
"membershipLevel === 'gold' || membershipLevel === 'platinum'"Example - Premium Member Badge
{
"type": "conditional",
"id": "premium-badge",
"props": {
"condition": "isPremium === true"
},
"children": [
{
"type": "container",
"id": "badge-container",
"props": {
"backgroundColor": "#ffd700",
"padding": "10px 20px",
"borderRadius": "20px",
"align": "center"
},
"children": [
{
"type": "text",
"id": "badge-text",
"content": "⭐ Premium Member",
"style": {
"fontSize": 14,
"fontWeight": "bold",
"color": "#000000",
"textAlign": "center"
}
}
]
}
]
}Example - Discount Notice
{
"type": "conditional",
"id": "discount-notice",
"props": {
"condition": "orderTotal >= 100"
},
"children": [
{
"type": "container",
"id": "discount-banner",
"props": {
"backgroundColor": "#d4edda",
"padding": "15px",
"borderRadius": "4px",
"border": "1px solid #c3e6cb"
},
"children": [
{
"type": "text",
"id": "discount-text",
"content": "🎉 Congratulations! You've qualified for free shipping on orders over $100.",
"style": {
"color": "#155724",
"fontSize": 16,
"textAlign": "center"
}
}
]
}
]
}Example - Status-Based Content
{
"type": "conditional",
"id": "shipping-status",
"props": {
"condition": "status === 'shipped'"
},
"children": [
{
"type": "heading",
"id": "shipped-heading",
"props": { "level": 2 },
"content": "Your Order Has Shipped! 📦",
"style": { "color": "#28a745", "textAlign": "center" }
},
{
"type": "text",
"id": "tracking-info",
"content": "Track your package: {{trackingNumber}}",
"style": { "textAlign": "center" }
},
{
"type": "button",
"id": "track-button",
"props": {
"text": "Track Package",
"href": "https://example.com/tracking/{{trackingNumber}}",
"backgroundColor": "#28a745",
"alignment": "center"
}
}
]
}Use Cases
- Premium/VIP content
- Discount notifications
- Shipping status messages
- Membership tier benefits
- Conditional calls-to-action
- Personalized content sections
Interactive Components
Button
Call-to-action button with clickable link.
Template Support: Email templates only (not available in attachments)
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
text | string | Yes | - | Button text (supports {{variables}}) |
href | string | Yes | - | Button URL (supports {{variables}}) |
alignment | enum | No | left | Alignment: “left”, “center”, “right” |
backgroundColor | string | No | #007bff | Background color |
color | string | No | #ffffff | Text color |
borderRadius | string | No | ”4px” | Border radius |
fontSize | number | No | 16 | Font size (8-48) |
fontWeight | string | No | ”normal” | Font weight: “normal”, “bold”, etc. |
padding | string | No | ”12px 24px” | CSS padding value |
textDecoration | string | No | ”none” | Text decoration: “none”, “underline” |
Example - Primary CTA
{
"type": "button",
"id": "get-started-btn",
"props": {
"text": "Get Started",
"href": "https://example.com/signup",
"alignment": "center",
"backgroundColor": "#007bff",
"color": "#ffffff",
"borderRadius": "8px",
"fontSize": 18,
"fontWeight": "bold",
"padding": "16px 32px"
}
}Example - Dynamic URL
{
"type": "button",
"id": "view-order-btn",
"props": {
"text": "View Order #{{orderNumber}}",
"href": "https://example.com/orders/{{orderId}}",
"alignment": "center",
"backgroundColor": "#28a745",
"color": "#ffffff"
}
}Button Styling Presets
Primary Button (default):
{
"backgroundColor": "#007bff",
"color": "#ffffff",
"borderRadius": "4px",
"padding": "12px 24px"
}Success Button:
{
"backgroundColor": "#28a745",
"color": "#ffffff",
"borderRadius": "4px",
"padding": "12px 24px"
}Danger/Alert Button:
{
"backgroundColor": "#dc3545",
"color": "#ffffff",
"borderRadius": "4px",
"padding": "12px 24px"
}Secondary/Outline Button:
{
"backgroundColor": "transparent",
"color": "#007bff",
"border": "2px solid #007bff",
"borderRadius": "4px",
"padding": "10px 22px"
}Use Cases
- Call-to-action buttons
- Order confirmation links
- Account activation
- Password reset links
- Survey/feedback links
- Download buttons
QR Code
QR code component for scannable information.
Template Support: Email templates only (not available in attachments)
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
value | string | Yes | - | QR code content (max 2,953 chars, supports {{variables}}) |
size | number/string | No | 200 | QR code size (50-1000 pixels or CSS value) |
errorCorrectionLevel | enum | No | M | Error correction: “L” (7%), “M” (15%), “Q” (25%), “H” (30%) |
margin | number | No | 4 | Quiet zone margin (0-10) |
color | string | No | #000000 | Foreground color |
backgroundColor | string | No | #ffffff | Background color |
align | enum | No | left | Alignment: “left”, “center”, “right” |
alt | string | No | "" | Alt text for accessibility |
style | object | No | - | Additional styling |
Error Correction Levels
- L (Low): 7% error correction - smallest QR code, best for clean environments
- M (Medium): 15% error correction - balanced size and reliability (recommended)
- Q (Quartile): 25% error correction - good for printed materials
- H (High): 30% error correction - largest code, best for damaged/dirty environments
Example - Event Ticket
{
"type": "qr-code",
"id": "ticket-qr",
"props": {
"value": "TICKET:{{ticketId}}:{{eventId}}:{{attendeeEmail}}",
"size": 250,
"errorCorrectionLevel": "H",
"margin": 4,
"align": "center",
"alt": "Event Ticket QR Code"
}
}Example - vCard Contact
{
"type": "qr-code",
"id": "contact-qr",
"props": {
"value": "BEGIN:VCARD\nVERSION:3.0\nFN:{{fullName}}\nEMAIL:{{email}}\nTEL:{{phone}}\nEND:VCARD",
"size": 200,
"errorCorrectionLevel": "M",
"align": "center"
}
}Example - WiFi Credentials
{
"type": "qr-code",
"id": "wifi-qr",
"props": {
"value": "WIFI:T:WPA;S:{{networkName}};P:{{password}};;",
"size": 200,
"errorCorrectionLevel": "H",
"margin": 4,
"align": "center",
"alt": "WiFi Network QR Code"
}
}Example - Payment Link
{
"type": "qr-code",
"id": "payment-qr",
"props": {
"value": "https://example.com/pay/{{invoiceId}}?amount={{amount}}¤cy={{currency}}",
"size": 300,
"errorCorrectionLevel": "M",
"align": "center"
}
}Common QR Code Formats
URL:
https://example.com/pathEmail:
mailto:support@example.com?subject=Support%20RequestPhone:
tel:+1234567890SMS:
sms:+1234567890?body=HellovCard (Contact):
BEGIN:VCARD
VERSION:3.0
FN:John Doe
EMAIL:john@example.com
TEL:+1234567890
END:VCARDWiFi:
WIFI:T:WPA;S:NetworkName;P:Password;;Geo Location:
geo:37.7749,-122.4194Use Cases
- Event tickets
- Contact information sharing
- WiFi access
- Payment links
- Product authentication
- Mobile app downloads
- Survey links
- Loyalty program enrollment
Timeline
Status progression timeline component.
Template Support: Email templates only (not available in attachments)
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
statusesVariable | string | Yes | - | Variable containing array of statuses |
currentStatusVariable | string | Yes | - | Variable containing current status |
orientation | enum | No | horizontal | Orientation: “horizontal”, “vertical” |
size | enum | No | md | Size: “sm”, “md”, “lg” |
showDescriptions | boolean | No | true | Show status descriptions |
spacing | number/string | No | 40px | Spacing between steps |
colors | object | No | - | Color configuration |
fonts | object | No | - | Font configuration |
borders | object | No | - | Border configuration |
shadows | object | No | - | Shadow configuration |
connectingLine | object | No | - | Connecting line configuration |
iconMapping | object | No | - | Icon names for specific statuses |
Status Data Format
The statusesVariable should contain an array of status objects:
[
{
"status": "ordered",
"label": "Order Placed",
"description": "Your order has been received",
"icon": "check-circle" // optional
},
{
"status": "processing",
"label": "Processing",
"description": "We're preparing your order"
},
{
"status": "shipped",
"label": "Shipped",
"description": "Your order is on its way"
},
{
"status": "delivered",
"label": "Delivered",
"description": "Order delivered successfully"
}
]The currentStatusVariable should contain the current status key (e.g., "processing").
Colors Configuration
{
"colors": {
"completed": "#28a745",
"current": "#007bff",
"pending": "#6c757d",
"completedLine": "#28a745",
"pendingLine": "#dee2e6",
"completedText": "#28a745",
"currentText": "#007bff",
"pendingText": "#6c757d",
"descriptionText": "#666666"
}
}Fonts Configuration
{
"fonts": {
"family": "Arial, sans-serif",
"labelSize": 16,
"descriptionSize": 14,
"weight": "normal"
}
}Borders Configuration
{
"borders": {
"stepWidth": 2,
"stepStyle": "solid",
"stepRadius": "50%"
}
}Shadows Configuration
{
"shadows": {
"current": "0 0 10px rgba(0,123,255,0.5)",
"completed": "0 2px 4px rgba(0,0,0,0.1)"
}
}Connecting Line Configuration
{
"connectingLine": {
"style": "solid",
"thickness": 2,
"completedColor": "#28a745",
"pendingColor": "#dee2e6"
}
}Icon Mapping
Map status keys to specific Lucide icon names:
{
"iconMapping": {
"ordered": "shopping-cart",
"processing": "clock",
"shipped": "truck",
"delivered": "check-circle"
}
}Valid Icon Names: check, check-circle, circle, clock, mail, send, truck, package, shopping-cart, credit-card, user, file, alert-circle, x-circle, star, flag, calendar, box (35+ icons available)
Example - Order Timeline
{
"type": "timeline",
"id": "order-timeline",
"props": {
"statusesVariable": "{{orderStatuses}}",
"currentStatusVariable": "{{currentStatus}}",
"orientation": "horizontal",
"size": "md",
"showDescriptions": true,
"spacing": "60px",
"colors": {
"completed": "#28a745",
"current": "#007bff",
"pending": "#6c757d"
},
"iconMapping": {
"ordered": "shopping-cart",
"processing": "clock",
"shipped": "truck",
"delivered": "check-circle"
}
}
}Example - Vertical Timeline
{
"type": "timeline",
"id": "shipping-timeline",
"props": {
"statusesVariable": "{{shippingSteps}}",
"currentStatusVariable": "{{currentStep}}",
"orientation": "vertical",
"size": "lg",
"showDescriptions": true,
"spacing": "40px",
"colors": {
"completed": "#28a745",
"current": "#ffc107",
"pending": "#e0e0e0",
"completedLine": "#28a745",
"pendingLine": "#e0e0e0"
},
"borders": {
"stepWidth": 3,
"stepStyle": "solid",
"stepRadius": "50%"
},
"shadows": {
"current": "0 0 15px rgba(255,193,7,0.6)",
"completed": "0 2px 6px rgba(40,167,69,0.3)"
}
}
}Use Cases
- Order tracking
- Shipping status
- Onboarding progress
- Application status
- Project milestones
- Booking confirmation
- Multi-step processes
Advanced Components
Component Nesting Rules
Allowed Nesting:
- Container → any component (except itself)
- Columns → any component per column
- Table Layout → any component per cell
- Loop → most components (no nested loops or conditionals)
- Conditional → most components (no nested conditionals or loops)
Forbidden Nesting:
- Loop inside Loop
- Loop inside Conditional
- Conditional inside Loop
- Conditional inside Conditional
- Button inside Button
- QR Code inside QR Code
Component Positioning (Attachments Only)
For PDF and Excel attachments, most components support absolute positioning:
{
"position": {
"x": 100,
"y": 200
}
}x: Horizontal position in pixelsy: Vertical position in pixels (or “auto” for flow layout)
Variable References in Components
All text-based properties support Handlebars syntax:
Simple Variables:
{{userName}}
{{orderNumber}}
{{companyName}}Nested Properties:
{{user.firstName}}
{{order.shippingAddress.city}}
{{product.pricing.amount}}Array Elements (in loops):
{{item.name}}
{{product[0].price}}Constants:
{{COMPANY_NAME}}
{{SUPPORT_EMAIL}}
{{TAX_RATE}}Best Practices
Design Principles
1. Mobile-First Design
- Use
stackOnMobile: truefor columns - Limit image widths (max 600px for email)
- Use readable font sizes (16px minimum)
- Provide adequate spacing and padding
2. Accessibility
- Always include
alttext for images - Use semantic heading levels (H1 → H2 → H3)
- Ensure sufficient color contrast (4.5:1 minimum)
- Provide descriptive button text
3. Performance
- Optimize image sizes before uploading
- Limit nested component depth (max 5 levels)
- Use calculated columns instead of loops when possible
- Minimize HTML Fragment usage
4. Consistency
- Use consistent colors throughout template
- Maintain uniform spacing between sections
- Apply consistent button styling
- Use standard font sizes for hierarchy
Component Selection Guide
When to use Container:
- Group related content
- Apply consistent styling to sections
- Create visual cards or panels
- Control maximum width
When to use Columns:
- Side-by-side layouts
- Feature grids
- Responsive layouts that stack on mobile
When to use Table Layout:
- Fixed grid positioning
- Label-value pairs
- Simple structured data without headers
When to use Table:
- Tabular data with headers
- Dynamic data from arrays
- Calculations and formulas
- Sortable/filterable data
When to use Loop:
- Repeating content blocks
- Product listings
- Dynamic item counts
- Personalized content per item
When to use Conditional:
- Show/hide based on user attributes
- Personalized content
- Status-dependent sections
- Feature toggles
Common Patterns
Pattern: Product Grid
{
"type": "columns",
"id": "product-grid",
"props": { "columnCount": 3, "gap": "20px", "stackOnMobile": true },
"children": [
{
"type": "loop",
"id": "product-loop",
"props": { "dataSource": "{{products}}", "itemVariable": "product" },
"children": [
{
"type": "container",
"id": "product-card",
"props": { "padding": "20px", "backgroundColor": "#f8f9fa", "borderRadius": "8px" },
"children": [
{
"type": "image",
"id": "product-image",
"props": { "source": "{{product.imageUrl}}", "width": 200, "alignment": "center" }
},
{
"type": "heading",
"id": "product-name",
"props": { "level": 4 },
"content": "{{product.name}}"
},
{
"type": "text",
"id": "product-price",
"content": "${{product.price}}"
},
{
"type": "button",
"id": "buy-button",
"props": { "text": "Buy Now", "href": "{{product.buyUrl}}", "alignment": "center" }
}
]
}
]
}
]
}Pattern: Invoice Header
{
"type": "columns",
"id": "invoice-header",
"props": { "columnCount": 2, "gap": "20px" },
"children": [
{
"type": "container",
"id": "company-info",
"children": [
{
"type": "image",
"id": "logo",
"props": { "source": "{{companyLogo}}", "width": 150 }
},
{
"type": "text",
"id": "company-name",
"content": "{{companyName}}"
},
{
"type": "text",
"id": "company-address",
"content": "{{companyAddress}}"
}
]
},
{
"type": "table-layout",
"id": "invoice-details",
"props": { "rows": 3, "cols": 2, "cellPadding": "8px" },
"children": [
{ "type": "text", "id": "invoice-label", "content": "Invoice #:", "style": { "fontWeight": "bold" } },
{ "type": "text", "id": "invoice-num", "content": "{{invoiceNumber}}" },
{ "type": "text", "id": "date-label", "content": "Date:", "style": { "fontWeight": "bold" } },
{ "type": "text", "id": "date-value", "content": "{{invoiceDate}}" },
{ "type": "text", "id": "due-label", "content": "Due Date:", "style": { "fontWeight": "bold" } },
{ "type": "text", "id": "due-value", "content": "{{dueDate}}" }
]
}
]
}Pattern: Status Card with Conditional
{
"type": "container",
"id": "status-card",
"props": {
"padding": "20px",
"borderRadius": "8px",
"backgroundColor": "#ffffff",
"border": "2px solid #dee2e6"
},
"children": [
{
"type": "heading",
"id": "status-title",
"props": { "level": 2 },
"content": "Order Status"
},
{
"type": "conditional",
"id": "pending-status",
"props": { "condition": "status === 'pending'" },
"children": [
{
"type": "container",
"id": "pending-container",
"props": { "backgroundColor": "#fff3cd", "padding": "15px", "borderRadius": "4px" },
"children": [
{
"type": "text",
"id": "pending-text",
"content": "⏳ Your order is being processed.",
"style": { "color": "#856404" }
}
]
}
]
},
{
"type": "conditional",
"id": "shipped-status",
"props": { "condition": "status === 'shipped'" },
"children": [
{
"type": "container",
"id": "shipped-container",
"props": { "backgroundColor": "#d4edda", "padding": "15px", "borderRadius": "4px" },
"children": [
{
"type": "text",
"id": "shipped-text",
"content": "📦 Your order has shipped! Track: {{trackingNumber}}",
"style": { "color": "#155724" }
},
{
"type": "button",
"id": "track-button",
"props": {
"text": "Track Package",
"href": "{{trackingUrl}}",
"backgroundColor": "#28a745",
"alignment": "center"
}
}
]
}
]
}
]
}Complete Examples
Example 1: Order Confirmation Email
{
"subject": "Order Confirmation #{{orderNumber}}",
"preheader": "Thank you for your order!",
"body": [
{
"type": "container",
"id": "header",
"props": {
"backgroundColor": "#007bff",
"padding": "30px 20px",
"maxWidth": "600px"
},
"children": [
{
"type": "image",
"id": "logo",
"props": {
"source": "https://example.com/logo-white.png",
"width": 200,
"alignment": "center"
}
}
]
},
{
"type": "container",
"id": "main-content",
"props": {
"padding": "40px 20px",
"maxWidth": "600px",
"backgroundColor": "#ffffff"
},
"children": [
{
"type": "heading",
"id": "thank-you",
"props": { "level": 1 },
"content": "Thank You for Your Order!",
"style": { "textAlign": "center", "color": "#333333" }
},
{
"type": "text",
"id": "confirmation-message",
"content": "Hi {{customerName}}, we've received your order and will send you shipping confirmation as soon as your order ships.",
"style": { "textAlign": "center", "fontSize": 16, "color": "#666666" }
},
{
"type": "spacer",
"id": "spacer-1",
"props": { "height": "30px" }
},
{
"type": "table-layout",
"id": "order-info",
"props": {
"rows": 3,
"cols": 2,
"borderWidth": "0px",
"cellPadding": "10px",
"width": "100%"
},
"children": [
{ "type": "text", "id": "order-label", "content": "Order Number:", "style": { "fontWeight": "bold" } },
{ "type": "text", "id": "order-value", "content": "{{orderNumber}}" },
{ "type": "text", "id": "date-label", "content": "Order Date:", "style": { "fontWeight": "bold" } },
{ "type": "text", "id": "date-value", "content": "{{orderDate}}" },
{ "type": "text", "id": "total-label", "content": "Total:", "style": { "fontWeight": "bold" } },
{ "type": "text", "id": "total-value", "content": "${{orderTotal}}", "style": { "fontWeight": "bold", "color": "#007bff" } }
]
},
{
"type": "spacer",
"id": "spacer-2",
"props": { "height": "30px" }
},
{
"type": "divider",
"id": "divider-1",
"props": { "thickness": 2, "color": "#e0e0e0" }
},
{
"type": "spacer",
"id": "spacer-3",
"props": { "height": "30px" }
},
{
"type": "heading",
"id": "items-heading",
"props": { "level": 2 },
"content": "Order Items",
"style": { "color": "#333333" }
},
{
"type": "table",
"id": "order-items",
"props": {
"dataSource": "{{orderItems}}",
"showHeader": true,
"columns": [
{ "header": "Item", "field": "name", "width": "50%", "align": "left" },
{ "header": "Qty", "field": "quantity", "width": "15%", "align": "center" },
{ "header": "Price", "field": "unitPrice", "width": "20%", "align": "right", "format": { "type": "number", "preset": "CURRENCY", "currency": "USD" } },
{ "header": "Total", "isCalculated": true, "expression": "quantity * unitPrice", "width": "15%", "align": "right", "format": { "type": "number", "preset": "CURRENCY", "currency": "USD" } }
]
}
},
{
"type": "spacer",
"id": "spacer-4",
"props": { "height": "30px" }
},
{
"type": "button",
"id": "view-order-button",
"props": {
"text": "View Order Details",
"href": "https://example.com/orders/{{orderId}}",
"alignment": "center",
"backgroundColor": "#007bff",
"padding": "16px 32px",
"fontSize": 18
}
}
]
},
{
"type": "container",
"id": "footer",
"props": {
"backgroundColor": "#f8f9fa",
"padding": "30px 20px",
"maxWidth": "600px"
},
"children": [
{
"type": "text",
"id": "footer-text",
"content": "Questions? Contact us at support@example.com",
"style": { "textAlign": "center", "fontSize": 14, "color": "#666666" }
}
]
}
]
}Example 2: Sales Report (PDF Attachment)
{
"title": "Monthly Sales Report",
"body": [
{
"type": "heading",
"id": "report-title",
"props": { "level": 1 },
"content": "Sales Report - {{reportMonth}}",
"style": { "fontSize": 24, "fontWeight": "bold", "color": "#333333" }
},
{
"type": "text",
"id": "generated-date",
"content": "Generated: {{generatedDate}}",
"style": { "fontSize": 12, "color": "#666666" }
},
{
"type": "spacer",
"id": "spacer-1",
"props": { "height": "20px" }
},
{
"type": "columns",
"id": "summary-cards",
"props": { "columnCount": 3, "gap": "20px" },
"children": [
{
"type": "container",
"id": "revenue-card",
"props": { "padding": "20px", "backgroundColor": "#e7f3ff", "borderRadius": "8px" },
"children": [
{ "type": "text", "id": "revenue-label", "content": "Total Revenue", "style": { "fontSize": 14, "color": "#666666" } },
{ "type": "text", "id": "revenue-value", "content": "${{totalRevenue}}", "style": { "fontSize": 28, "fontWeight": "bold", "color": "#007bff" } }
]
},
{
"type": "container",
"id": "orders-card",
"props": { "padding": "20px", "backgroundColor": "#d4edda", "borderRadius": "8px" },
"children": [
{ "type": "text", "id": "orders-label", "content": "Total Orders", "style": { "fontSize": 14, "color": "#666666" } },
{ "type": "text", "id": "orders-value", "content": "{{totalOrders}}", "style": { "fontSize": 28, "fontWeight": "bold", "color": "#28a745" } }
]
},
{
"type": "container",
"id": "avg-card",
"props": { "padding": "20px", "backgroundColor": "#fff3cd", "borderRadius": "8px" },
"children": [
{ "type": "text", "id": "avg-label", "content": "Avg Order Value", "style": { "fontSize": 14, "color": "#666666" } },
{ "type": "text", "id": "avg-value", "content": "${{avgOrderValue}}", "style": { "fontSize": 28, "fontWeight": "bold", "color": "#ffc107" } }
]
}
]
},
{
"type": "spacer",
"id": "spacer-2",
"props": { "height": "30px" }
},
{
"type": "chart",
"id": "revenue-chart",
"props": {
"chartType": "bar",
"dataSource": "{{dailySales}}",
"xAxis": "date",
"yAxis": "revenue",
"title": "Daily Revenue",
"width": 800,
"height": 400,
"xAxisLabel": "Date",
"yAxisLabel": "Revenue ($)",
"style": {
"colors": ["#007bff"],
"showGridLines": true,
"backgroundColor": "#ffffff"
}
}
},
{
"type": "spacer",
"id": "spacer-3",
"props": { "height": "30px" }
},
{
"type": "heading",
"id": "products-heading",
"props": { "level": 2 },
"content": "Top Products",
"style": { "fontSize": 20, "fontWeight": "bold" }
},
{
"type": "table",
"id": "top-products",
"props": {
"dataSource": "{{topProducts}}",
"showHeader": true,
"showTotalsRow": true,
"totalsConfig": {
"label": "Total",
"labelColumn": "productName",
"aggregations": {
"unitsSold": "SUM",
"revenue": "SUM"
}
},
"columns": [
{ "header": "Product", "field": "productName", "width": "40%", "align": "left" },
{ "header": "Units Sold", "field": "unitsSold", "width": "20%", "align": "center" },
{ "header": "Revenue", "field": "revenue", "width": "20%", "align": "right", "format": { "type": "number", "preset": "CURRENCY", "currency": "USD" } },
{ "header": "% of Total", "isCalculated": true, "expression": "(revenue / totalRevenue) * 100", "width": "20%", "align": "right", "format": { "type": "number", "preset": "PERCENT", "decimals": 1 } }
]
}
}
]
}Example 3: Event Invitation with QR Code
{
"subject": "You're Invited: {{eventName}}",
"preheader": "{{eventDate}} at {{eventLocation}}",
"body": [
{
"type": "container",
"id": "hero",
"props": {
"backgroundColor": "#667eea",
"padding": "60px 20px",
"maxWidth": "600px"
},
"children": [
{
"type": "heading",
"id": "event-title",
"props": { "level": 1 },
"content": "{{eventName}}",
"style": { "fontSize": 32, "fontWeight": "bold", "color": "#ffffff", "textAlign": "center" }
},
{
"type": "text",
"id": "event-tagline",
"content": "{{eventTagline}}",
"style": { "fontSize": 18, "color": "rgba(255,255,255,0.9)", "textAlign": "center" }
}
]
},
{
"type": "container",
"id": "main-content",
"props": {
"padding": "40px 20px",
"maxWidth": "600px",
"backgroundColor": "#ffffff"
},
"children": [
{
"type": "text",
"id": "greeting",
"content": "Hi {{attendeeName}},",
"style": { "fontSize": 18, "fontWeight": "bold", "color": "#333333" }
},
{
"type": "spacer",
"id": "spacer-1",
"props": { "height": "15px" }
},
{
"type": "text",
"id": "invitation-text",
"content": "You're invited to join us for {{eventName}}! We're excited to have you there.",
"style": { "fontSize": 16, "color": "#666666", "lineHeight": 1.6 }
},
{
"type": "spacer",
"id": "spacer-2",
"props": { "height": "30px" }
},
{
"type": "divider",
"id": "divider-1",
"props": { "thickness": 1, "color": "#e0e0e0" }
},
{
"type": "spacer",
"id": "spacer-3",
"props": { "height": "30px" }
},
{
"type": "columns",
"id": "event-details",
"props": { "columnCount": 2, "gap": "20px" },
"children": [
{
"type": "container",
"id": "details-left",
"children": [
{ "type": "text", "id": "date-label", "content": "📅 Date", "style": { "fontSize": 14, "fontWeight": "bold", "color": "#999999" } },
{ "type": "text", "id": "date-value", "content": "{{eventDate}}", "style": { "fontSize": 16, "color": "#333333", "marginTop": "5px" } },
{ "type": "spacer", "id": "detail-spacer-1", "props": { "height": "15px" } },
{ "type": "text", "id": "time-label", "content": "🕐 Time", "style": { "fontSize": 14, "fontWeight": "bold", "color": "#999999" } },
{ "type": "text", "id": "time-value", "content": "{{eventTime}}", "style": { "fontSize": 16, "color": "#333333", "marginTop": "5px" } }
]
},
{
"type": "container",
"id": "details-right",
"children": [
{ "type": "text", "id": "location-label", "content": "📍 Location", "style": { "fontSize": 14, "fontWeight": "bold", "color": "#999999" } },
{ "type": "text", "id": "location-value", "content": "{{eventLocation}}", "style": { "fontSize": 16, "color": "#333333", "marginTop": "5px" } },
{ "type": "spacer", "id": "detail-spacer-2", "props": { "height": "15px" } },
{ "type": "text", "id": "dress-label", "content": "👔 Dress Code", "style": { "fontSize": 14, "fontWeight": "bold", "color": "#999999" } },
{ "type": "text", "id": "dress-value", "content": "{{dressCode}}", "style": { "fontSize": 16, "color": "#333333", "marginTop": "5px" } }
]
}
]
},
{
"type": "spacer",
"id": "spacer-4",
"props": { "height": "30px" }
},
{
"type": "divider",
"id": "divider-2",
"props": { "thickness": 1, "color": "#e0e0e0" }
},
{
"type": "spacer",
"id": "spacer-5",
"props": { "height": "30px" }
},
{
"type": "heading",
"id": "ticket-heading",
"props": { "level": 2 },
"content": "Your Ticket",
"style": { "fontSize": 20, "textAlign": "center", "color": "#333333" }
},
{
"type": "text",
"id": "ticket-instructions",
"content": "Present this QR code at the entrance for quick check-in",
"style": { "fontSize": 14, "textAlign": "center", "color": "#666666" }
},
{
"type": "spacer",
"id": "spacer-6",
"props": { "height": "20px" }
},
{
"type": "qr-code",
"id": "ticket-qr",
"props": {
"value": "EVENT:{{eventId}}:ATTENDEE:{{attendeeId}}:TICKET:{{ticketId}}",
"size": 250,
"errorCorrectionLevel": "H",
"align": "center",
"alt": "Event Ticket QR Code"
}
},
{
"type": "text",
"id": "ticket-number",
"content": "Ticket #{{ticketId}}",
"style": { "fontSize": 12, "textAlign": "center", "color": "#999999", "marginTop": "10px" }
},
{
"type": "spacer",
"id": "spacer-7",
"props": { "height": "30px" }
},
{
"type": "button",
"id": "add-calendar-button",
"props": {
"text": "Add to Calendar",
"href": "{{calendarLink}}",
"alignment": "center",
"backgroundColor": "#667eea",
"padding": "14px 28px"
}
}
]
},
{
"type": "container",
"id": "footer",
"props": {
"backgroundColor": "#f8f9fa",
"padding": "30px 20px",
"maxWidth": "600px"
},
"children": [
{
"type": "text",
"id": "footer-text",
"content": "Can't make it? Let us know at {{eventEmail}}",
"style": { "textAlign": "center", "fontSize": 14, "color": "#666666" }
}
]
}
]
}Summary
This guide covered all 18 available template components across 4 categories:
- 5 Layout Components: Container, Columns, Table Layout, Divider, Spacer
- 6 Content Components: Text, Heading, Rich Text, Image, List, HTML Fragment
- 4 Data Components: Table, Chart, Loop, Conditional
- 3 Interactive Components: Button, QR Code, Timeline
Each component includes detailed property specifications, examples, and use cases. Combined with the Variables & Dynamic Content guide, you have everything needed to create powerful, dynamic templates for emails and attachments.
For more information:
- Variables & Dynamic Content - Variables, calculated variables, and data tables
- Email Designer - Visual email template editor
- Attachment Designer - PDF and Excel template editor
- Templates - Template management overview
Need Help? Contact support at support@example.com or visit our documentation at https://docs.example.com