Merge tags
PersonalizationMerge tags
Merge tags let users drop {{tokens}}, like {{first_name}}, into text, links, image sources, and alt text. You supply the pickable set from your backend.
Passing tags#
In the drop-in editor, pass them via options.mergeTags (react-email-editor parity, grouped arrays/objects are flattened automatically):
<EmailEditor
options={{
mergeTags: [
{ name: "First Name", value: "{{ user.first_name }}", sample: "Ada" }, { name: "Account", mergeTags: [ // nested group
{ name: "Plan", value: "{{ account.plan }}", sample: "Pro" }
]}
]
}}
/>That becomes the flat map MailKaro uses internally:
{
"user.first_name": { label: "First Name", value: "{{ user.first_name }}", sample: "Ada" }, "account.plan": { label: "Account · Plan", value: "{{ account.plan }}", sample: "Pro" }
}With EmailEditor#
<EmailEditor
mergeTags={{
first_name: { label: "First name", value: "{{first_name}}", sample: "Alex" }
}}
/>Conditions and lists#
Text can also show or repeat parts of itself, based on the recipient. A condition shows its first part when it holds and its second part otherwise:
{{#if plan == "pro"}}Thanks for being a Pro customer.{{else}}Upgrade to Pro today.{{/if}}A list repeats its body once per item. Give the list as an array in the values you render with (items can be text or records):
{{#each orders}}
{{@number}}. {{name}}, {{this.total}}{{#if @last}}.{{else}};{{/if}}
{{/each}}renderDesign(design, {
fullDocument: true,
mergeTags: { plan: "pro", orders: [{ name: "Chai", total: "40" }, { name: "Coffee", total: "90" }] }
});| Property | Controls | Default |
|---|---|---|
{{#if expr}}...{{else}}...{{/if}} | Same expressions as display conditions: ==, !=, <, >, &&, ||, !, brackets, text and numbers. An expression that cannot be read counts as false. | , |
{{#each list}}...{{/each}} | Repeats for each item, up to 100. | , |
{{name}} or {{this.name}} | A field of the current item. Outside tags still work inside the loop. | , |
{{this}} | The item itself, when the list holds plain text or numbers. | , |
{{@index}}, {{@number}}, {{@first}}, {{@last}} | Position in the loop: from 0, from 1, and whether it is the first or last item. Conditions can use them too. | , |
POST /v3/render and the MCP render_design tool accept the same lists in merge_tags.Resolving at send time#
The sample values preview in the editor. When you render on the server, pass real recipient values so {{first_name}} becomes the actual name.
/embed/runtime returns merge_tags for the project, separate from the client options.mergeTags.