What a merge tag actually does
A merge tag is a placeholder you drop into your email subject or body that AcelleMail replaces — per recipient, at send time — with that subscriber's actual value.
Subject Hey {{ subscriber.first_name }}, your invoice for July becomes Hey Maria, your invoice for July for Maria, Hey Tobias, your invoice for July for Tobias.
The values come from list fields — every list has at least email + first_name + last_name, and you can add unlimited custom fields like city, signup_plan, last_purchase_total.
Insert a merge tag from the campaign builder
1. Start typing in the subject line
In any campaign, the Subject field accepts merge tags inline. Click the field and start typing — AcelleMail shows a hint about merge-tag insertion:

You can paste a tag directly ({{ subscriber.first_name }}) OR open the picker for the full list.
2. The merge-tag picker (autosuggest)
Type {{ in the subject — or open the body builder's right-side panel — and the autosuggest dropdown lists every available tag, scoped to this list's actual fields:

Click a tag to insert it. The picker scopes to:
- Subscriber fields — every column on your list (
email,first_name, custom fields) - System tags —
{{ unsubscribe_url }},{{ web_view_url }},{{ campaign.name }},{{ send_date }} - Conditional helpers —
{% if %}...{% endif %}(Twig syntax — see Advanced)
3. Manage the list's custom fields
The picker only shows fields that exist on the list. To add a new field, Audience → [list] → Fields:

For each field, set:
- Tag (the key) — e.g.
citybecomes{{ subscriber.city }}in emails - Type — text / number / date / dropdown / multi-select
- Required at signup — appears on the signup form, blocks if blank
- Default value — fallback for existing subscribers without this field set
After adding a field, re-run an import (or update via API) to back-fill values for existing subscribers — they won't be back-filled automatically.
Common UI patterns that work
| What you want | How to write it |
|---|---|
| First name with a fallback if unknown | Hi {{ subscriber.first_name | default('there') }} |
| Full name (joined) | {{ subscriber.first_name }} {{ subscriber.last_name }} |
| Date formatting | {{ subscriber.signup_date | date('F j, Y') }} |
| Uppercase a value | {{ subscriber.city | upper }} |
| Truncate a string | {{ subscriber.bio | truncate(80) }} |
| Numeric formatting | ${{ subscriber.lifetime_value | number_format(2) }} |
These filters use Twig syntax — the AcelleMail builder renders them at send time. You can test any tag by clicking Preview in the campaign builder and toggling the Use sample subscriber dropdown:

Common pitfalls + UI fixes
| Symptom | Likely cause | UI fix |
|---|---|---|
Email shows literal {{ subscriber.city }} instead of "Berlin" |
Field doesn't exist on this list, OR typo in tag name | Open Audience → [list] → Fields — confirm the tag matches exactly |
| First name field empty for half the list | Imported CSV had no first_name column |
Use | default('friend') filter, OR re-export source + re-import with field mapping |
| Picker doesn't show a field you added | Page cached pre-add | Hard refresh (Cmd-Shift-R / Ctrl-F5), or close + reopen the builder |
| Subject renders blank for some recipients | The field is empty for those subscribers + no default filter |
Add | default('something') to the merge tag |
Advanced: Twig conditionals, loops, and computed merge tags
AcelleMail's body and subject support the full Twig templating language — including conditionals and loops — for cases the autosuggest picker doesn't cover.
Conditional content blocks:
{% if subscriber.signup_plan == 'enterprise' %}
<p>Your Enterprise account manager is Sarah — book a call here.</p>
{% elseif subscriber.signup_plan == 'pro' %}
<p>Pro users get priority support — reply to this email anytime.</p>
{% else %}
<p>Get faster response times by upgrading.</p>
{% endif %}
Tag-based blocks (using the multi-value tags field):
{% if 'vip' in subscriber.tags %}
<p>VIP early access: <a href="...">claim your slot</a></p>
{% endif %}
Loops over array fields (when a custom field is JSON-encoded list):
<ul>
{% for product in subscriber.recent_purchases %}
<li>{{ product.name }} — ${{ product.price }}</li>
{% endfor %}
</ul>
Computed values inline:
{% set discount = subscriber.lifetime_value > 500 ? 20 : 10 %}
Your loyalty discount: {{ discount }}%
Default filter chains for safety:
Hi {{ (subscriber.first_name | default(subscriber.email | split('@') | first)) | capitalize }}
This says: try first_name, fall back to the part of the email before @, then capitalize. Bullet-proof against missing fields.
Per-campaign override fields — if you need a value computed at send time (e.g. discount code unique per recipient), use the AcelleMail API to populate a custom field just before launching the campaign, OR set up an automation that sets the field when the trigger fires.
For a deeper Twig reference, the upstream syntax docs at twig.symfony.com apply directly — AcelleMail uses Twig 3.x.
Related articles
- Email template design — best practices
- Importing contacts CSV — best practices and field mapping
- Building a welcome email series in AcelleMail
- Setting up UTM parameters for campaign tracking
7 bình luận