New guide: how to warm up a dedicated IP without hurting your reputation. Read now →
Log in
MigoSMTP
Sending and campaignsUpdated 15 Oct 2026

Email Template Personalization Done Safely: Variables, Fallbacks, Escaping and Localization

Personalization is one of the easiest ways to make an email useful and one of the easiest ways to embarrass yourself. This guide covers merge variables, fallback values for missing data, escaping and injection, conditional blocks, localization of language, dates, currency and right-to-left text, template versioning and review, preview data sets, subject-line pitfalls and plain-text parity.

ML
Written by Mei Lin Tan
Email Analytics Analyst
Reviewed by Camille Laurent
  • Published2 Oct 2026
  • Read time16 min
  • Length3,354 words
Share this guide

Email template personalization turns one message into thousands of individual ones, and every one of those messages is only as good as the data that fills it in. When the data is clean, a recipient sees their own name, plan, language and currency. When it is not, they see Hi , or Hello {{first_name}} or a price in the wrong format, and they stop trusting everything else in the message. This guide shows how we build personalized templates that fail gracefully, stay safe against injection, work across languages, and can be reviewed and tested like any other piece of software.

4contexts that need different escaping: HTML text, HTML attributes, URLs and headers
2parts to keep identical in logic: HTML and plain text
1safe default needed for every variable that can be empty
0unresolved placeholders allowed to leave your system

How merge variables and templates work

A template is a message with holes in it. A merge variable, sometimes called a tag, token or placeholder, is a named hole such as first_name or order_total. At send time a rendering engine takes one record of data, replaces each hole with the record value and produces the final message. Different tools use different syntax, usually double curly braces or percent signs, but the principles below hold for all of them.

There are four moving parts, and most personalization bugs sit in the gaps between them: the data source (your database, CRM or API payload), the mapping that connects fields to variables, the template that uses them, and the renderer that does the substitution. A field can be renamed in the source while the template still points at the old name. A mapping can pass an empty string where the template expects a value. A renderer can leave an unknown placeholder untouched, which is how raw curly braces reach inboxes.

FailureWhat the recipient seesTypical cause
Empty valueHi , your order is readyField is blank in the source and no fallback exists
Placeholder text stored as dataHello null or Hello undefinedImport or code stored the literal word instead of an empty value
Unresolved tagHello {{first_name}}Variable name misspelled, renamed or not supplied for this send
Wrong case or formatHello JOHN SMITHRaw data entered in capitals, with no normalization
Wrong language or formatA French customer gets English text and a US dateNo locale on the record, or the default was used without checking
OverflowA 90-character company name breaks the layoutNo length limit or layout test for long values

Treat each of these as a category of test case. If your template survives an empty value, a placeholder-looking value, a missing key, an odd case, a missing locale and a very long value, it is already more robust than most.

Fallback values: avoiding Hi , failures

A fallback is a decision made in advance. Instead of hoping that every record has a first name, you decide what the email says when it does not. There are three good patterns, and we usually prefer the first or second.

  1. Rewrite so the value is not needed. Replace Hi {{first_name}}, with a greeting that works for everyone, or put the personalization somewhere it is optional, such as a sentence about their plan or recent activity.
  2. Use a neutral default. Hello, or Hello there, or the team name for business accounts. It costs nothing and cannot look broken.
  3. Skip the block. If a whole paragraph depends on a value, make it a conditional block that disappears when the value is empty (see the next sections).

What we avoid is a fallback that pretends to know something. Using Valued customer in a message that is clearly about one person reads as a form letter, and a guessed name from an email address, such as turning j.smith99 into J, is worse than no name. When you do not know, say less.

Clean the data, not just the template

Fallbacks protect the output, but the data itself deserves attention. Normalize at the point of entry or import: trim spaces, treat the strings null, none, n/a and a single dash as empty, and decide how to display capitalization. Be careful with automatic capitalization rules, because names such as McDonald, de la Cruz or van der Berg do not follow simple patterns. When in doubt, keep what the person typed and only fix obvious cases like all-capital or all-lowercase entries. The same care applies to addresses you collect, which is covered in our guide to email validation before sending.

A template with fallbacks and conditions

The exact syntax depends on the engine, so check your MigoSMTP account or API documentation for what your sending method supports. The example below uses an invented, generic syntax to show the shape: a default filter, a condition with an else branch, and escaping applied to every value.

Subject: {{ subject_line | default: "Your order update" }}

{% if first_name %}
Hello {{ first_name | escape }},
{% else %}
Hello,
{% endif %}

Your order {{ order_id | escape }} is on its way.

{% if tracking_url %}
Track it here: {{ tracking_url | url_encode }}
{% else %}
We will send tracking details as soon as they are available.
{% endif %}

{% if coupon_code and coupon_expires %}
Use code {{ coupon_code | escape }} before {{ coupon_expires | date: locale }}.
{% endif %}

Notice that every branch produces a complete, sensible message. The coupon block has two conditions, because a code without an expiry date, or the reverse, would produce a half sentence. Conditions that depend on several fields should check all of them.

Escaping, HTML injection and header injection

Anything a person can type into a form, a profile or an order note is untrusted input, and personalization places that input inside your message. If values go in unchanged, two kinds of problem appear.

HTML injection. A value containing angle brackets or quotes can change the structure of your HTML. At best a name like Tom & Jerry breaks the display. At worst someone enters a link or image tag as their name, and your trusted sending domain delivers content they wrote, with your branding around it. Mail clients block scripts, but links, images, hidden text and layout tricks still work, which is enough for phishing-style abuse.

Header injection. Headers are separated by line breaks. If a value placed in a header, such as the subject, a recipient name in the To field or a Reply-To address, contains a carriage return or line feed followed by text like Bcc: someone@example.net, a naive system may treat the rest as a new header. Modern libraries and sending APIs reject or encode this, but you should not rely on that alone when you build messages yourself.

Where the value goesWhat to doWhy
HTML body textHTML-encode angle brackets, ampersands and quotesStops values from being read as markup
HTML attribute (title, alt, href)Encode for attributes, and validate that a URL starts with http or httpsQuotes can close the attribute and add new ones; some URL schemes are unsafe
URL query stringURL-encode the valueSpaces, ampersands and hash signs change the meaning of a link
Subject, To, From, Reply-ToRemove carriage returns and line feeds, and encode non-ASCII text correctlyLine breaks create new headers; non-ASCII needs encoded words (RFC 2047) or a modern equivalent
Plain-text bodyRemove control characters; no HTML encoding neededEncoding would show visible entity text instead of the character
Dynamic links in generalAllow only your own domains or an allow-list for redirect targetsPrevents your tracked links from being used as open redirects

Two rules keep this manageable. First, escape at output, not at input, because the same stored value may be used in HTML, plain text and a header, and each needs different treatment. Second, make escaping the default in the template engine so that unsafe output must be requested on purpose. If you are building messages by hand, our overview of MIME structure and encoding explains how the parts and headers fit together.

Conditional blocks and dynamic content

Conditional blocks let one template serve many audiences: show a renewal notice only to people whose plan renews this month, show a regional paragraph only in some countries, hide the discount line when there is no discount. They are powerful, and they multiply the number of messages you actually send. A template with five independent conditions can render in 32 different ways.

  • Always give the condition a complete else path. The default should be a message you would be happy to send to anyone.
  • Keep conditions simple and few. Past a handful of branches, split into separate templates for separate audiences. They are easier to review and to test.
  • Base conditions on data you trust. A flag set by a nightly job that sometimes fails is a risk. Decide what happens when the flag is missing.
  • Do not hide legal or required content behind conditions. The unsubscribe link, sender identity and postal address of a commercial message should render for everyone. General information, not legal advice: check the rules that apply to you.
  • Test the combinations. At minimum test every branch of every condition once, plus the all-empty and all-filled cases.

Keep personalization that depends on behaviour sensible too. A line such as We noticed you looked at this item can feel helpful or invasive depending on the audience and on what you told them when you collected the data. Our guide to separating transactional and marketing streams also matters here, because transactional templates, such as receipts, need stricter correctness and fewer promotional conditions than campaigns.

Localization: language, dates, currency and right-to-left text

Localization is more than translation. A message in the right language can still look wrong if the date reads as month first for a recipient who expects day first, if the price uses the wrong separators, or if a right-to-left language displays in the wrong direction. Store a locale on each recipient, such as a language plus an optional region, and use it for everything below.

ItemExample of the problemSafer approach
LanguageRecipient reads Hindi, receives English onlyOne template per language, chosen by the stored language, with a defined default language
Dates03/04/2027 means 3 April or 4 March depending on the readerFormat with the locale, or write the month as a word
Time zonesA deadline of 18:00 with no zoneState the zone or convert to the recipient local time
Numbers1,234.50 versus 1.234,50 versus 12,34,567.00Use a locale-aware formatter rather than building strings by hand
CurrencyA bare 100 with no currency, or the symbol on the wrong sideStore amount and currency code separately and format both together
Names and honorificsFamily name first in some cultures; no gendered titles in othersUse a preferred greeting name field or a name-free greeting
Right-to-leftArabic or Hebrew text left-aligned, punctuation and numbers misplacedSet the text direction, align accordingly and isolate embedded left-to-right text

Right-to-left details that are easy to miss

For Arabic, Hebrew, Persian and Urdu, set the direction on the container that holds the text, not only on the page body, because some mail clients ignore body attributes. Check that bullets, borders, padding, buttons and arrow icons mirror correctly. Names or product codes in Latin letters inside a right-to-left sentence can reorder punctuation unless they are wrapped so that their direction is isolated. The W3C internationalization guidance on inline bidirectional markup, linked below, explains the markup choices. Always send real test messages to the clients your audience uses, because rendering varies.

Character encoding matters as well. Send as UTF-8 and make sure the subject and the display names are encoded correctly, so that accented and non-Latin text arrives readable. Fonts also need to cover the script, and the fallback fonts in your CSS stack should include one that does. Layout and dark mode concerns overlap with the points in our accessible HTML email guide.

Subject-line personalization pitfalls and spam-filter impact

The subject line is the riskiest place for personalization, because a failure there is visible before the message is even opened, and because it is a header, with the injection considerations above. A few practical points follow.

  • Make the subject work without the variable. If the name is missing, the subject should still read naturally, so give it a default or use a version without the token.
  • Avoid mid-sentence capitalization problems. A name in all capitals, or a lowercase one, looks careless. Normalize the display, or leave the name out.
  • Do not fake familiarity. Forged Re: or Fwd: prefixes, invented prior conversations and urgent claims are deceptive, and are the sort of tactics that filters and recipients react badly to.
  • Watch length after substitution. A long company name can push the important words beyond what the mail client shows, so test the longest realistic values.
  • Stay accurate. Personalized claims that are wrong, such as the wrong product, the wrong amount or the wrong city, damage trust and increase complaints.
  • Measure beyond opens. Open data is unreliable for several reasons, covered in our note on Apple Mail Privacy Protection. Compare replies, clicks, unsubscribes and complaints between personalized and plain versions.

As for filters: a name in a subject line is not, by itself, a reason for a message to be filtered. Mailbox providers weigh authentication, sender reputation, recipient engagement and content quality. Personalization affects spam outcomes indirectly. It can help when it makes a message more relevant and wanted. It can hurt when it produces broken text, when it makes every message look unique to a naive content check while the body is still bulk-like, or when it hides a deceptive claim. For wider guidance on what filters look at, see our email content and spam filters guide.

Plain-text parity

Most marketing and transactional messages are sent as multipart messages with an HTML part and a plain-text alternative. The plain-text part is read by some mail clients, by accessibility tools in some setups, by smartwatches and previews, and it is looked at by filters. Personalization has to work the same in both parts.

  • Render both parts from the same record in the same operation, so they cannot disagree about the name, the amount or the offer.
  • Apply the same conditions. If the HTML hides the coupon block, the text part must hide it too.
  • Write the plain-text version deliberately instead of auto-stripping tags, and check that links remain readable, with the full URL visible.
  • Include the same required elements in both parts, such as the unsubscribe link and sender identity.
  • Do not HTML-encode values in the plain-text part. An ampersand should appear as an ampersand.
  • Keep the two roughly equal in content. A very different text part from the HTML is something both people and filters notice.

Template versioning, review and approval

Templates are code, even when they live in a visual editor. A single edit can change what thousands of people receive, so they deserve the habits of code: history, review and the ability to go back.

  1. Keep every version. Store templates in version control, or in a tool that keeps history with the author and date of each change.
  2. Name versions meaningfully. Use a short change note such as Added fallback for empty first name, not Updated.
  3. Require a second reader. The author is blind to their own typos. A reviewer checks variables, fallbacks, links, legal text and rendering of the preview set.
  4. Separate drafts from live templates. Never edit the template that a running automation uses. Edit a copy, test it and switch over.
  5. Record who owns each variable. When a data field changes, someone should know which templates depend on it.
  6. Keep a rollback. The last known good version should be one action away, because problems are found after sending starts.
  7. Retire what you do not use. Old templates with stale links and footers are an accident waiting for an automation to find them.

Preview and test data sets

Testing with one friendly record, such as a colleague with a short English name, proves almost nothing. Build a small, permanent preview set of records that are designed to break things, and render every template against all of them before release. Use invented data only, never real customers, and send the tests to a mail catcher or test addresses, as described in our guide to testing email safely.

Test recordContentsWhat it catches
EmptyAll optional fields blank or missingMissing fallbacks, Hi , greetings, half sentences
Placeholder-lookingFirst name stored as null, or as {{first_name}}Dirty data and double-substitution
LongCompany name of 90 characters, address with 5 linesLayout overflow and truncated subjects
Special charactersName like O'Brien & Sons with a quote, a tag-like string and an ampersandMissing escaping and broken attributes
Line breakName or subject field containing a line breakHeader injection handling
Accented and non-LatinNames in accented Latin, Devanagari, JapaneseEncoding problems and missing font coverage
Right-to-leftArabic or Hebrew language with a Latin product codeDirection and mixed-text ordering
Locale varietyLocales with different date, number and currency formatsHard-coded formats and wrong currency symbols

Add a send-time guard on top of the preview set. After rendering each message and before handing it off, scan the result for leftover placeholder syntax, an empty greeting pattern, the words null or undefined in a name position, and any line break in header values. If the scan fails, hold that message and alert a person, because one failed render is cheaper than a failed campaign.

A worked example: 50,000 messages and a missing name

A small online shop plans to send a renewal reminder to 50,000 customers. The template opens with Hi {{first_name}}, and has no fallback. Before the send, someone runs the preview set. The empty record shows Hi , and the placeholder-looking record shows Hi null,. A query of the customer table finds that 1.8 percent of records have a blank first name and a further 0.6 percent hold the text null from an old import.

That is 2.4 percent of 50,000, or 1,200 recipients who would have received a broken greeting: 900 with Hi , and 300 with Hi null,. Nobody would be harmed, but 1,200 people would see an obviously automatic message with a mistake in it, and some would reply or report it. The team makes three changes. A clean-up job turns null and blank names into empty values. The template uses Hello, as its fallback when the name is empty. A send-time guard blocks any rendered message that still starts with a pattern like Hi followed by a comma.

The preview set also reveals a second problem. One test record with a long company name wraps the subject line so that the renewal date drops out of view in the inbox list. The team moves the date to the start of the subject. The corrected campaign goes out with no broken greetings, and the preview set is kept for every later release. The numbers here are invented for illustration. Your own proportions will differ, which is exactly why you should look at your own data before sending.

A short checklist

  1. Every variable is listed with its source, owner and whether it can be empty.
  2. Every optional variable has a fallback or a conditional block with a complete default branch.
  3. Stored values are cleaned: blanks, null, none and placeholder strings are treated as empty.
  4. Output is escaped for its context: HTML text, attribute, URL and header.
  5. Header values (subject, names, reply address) cannot contain line breaks.
  6. Locale controls language, dates, time zones, numbers and currency, with defaults defined.
  7. Right-to-left languages have direction set and are tested in real mail clients.
  8. The subject line reads naturally with and without personalization, and makes no deceptive claims.
  9. Plain-text and HTML parts are rendered from the same data and apply the same conditions.
  10. Templates have version history, a reviewer, an owner and a rollback.
  11. A preview set of awkward records passes before each release, and a send-time guard blocks unresolved placeholders.

MigoSMTP delivers the messages your systems or tools render. Where exact template, variable or API behaviour matters, check your MigoSMTP account or API documentation for exact details, and test with your own preview set before a large send.

Want a second pair of eyes on your templates? Tell us how you build and send personalized email, and we will help you plan fallbacks, testing and a safe rollout.

Contact support

Further reading and sources

Frequently asked questions

What is a fallback value in an email template?

A fallback, also called a default, is the text a template uses when a merge variable has no value. For a missing first name it might be a neutral greeting such as Hello, or it might be a rewrite of the sentence that no longer needs a name. It is decided when the template is written, not left to chance at send time.

Why do some emails start with Hi , or Hello None?

The template inserted an empty or null value into a fixed sentence. The record had no first name, or an import stored the word null, none or a blank space, and nothing checked it. Fallbacks, a clean-up of stored data and a pre-send check for empty or placeholder-looking values prevent it.

Can personalization data be used to inject content into my emails?

Yes, if values are inserted without encoding. A name containing markup can change your HTML, and a value containing a line break can add headers when it is placed in a header such as the subject or reply address. Encode for the context, strip control characters from header values, and treat every field a customer can type as untrusted.

Should I put the recipient name in the subject line?

Test it rather than assume. A name can raise attention for some audiences, but a wrong, empty or oddly capitalized name hurts trust, and heavy use of personalization tokens in subjects can look like mass mail. Make sure the subject still reads well without the name and measure replies and complaints, not only opens.

Do personalized subject lines affect spam filtering?

Personalization alone is not a spam signal. Filters look at authentication, reputation, content and recipient behaviour. Problems come from broken output, such as unresolved placeholders, or from misleading tricks like a fake Re: prefix with the name. Accurate, relevant personalization is neutral at worst.

How should I handle names in languages with different name order?

Do not assume first name then last name. Store a full name, a preferred greeting name and, if you need it, separate fields, and let the recipient supply how they want to be addressed. When you only have a full name and no way to split it reliably, use a greeting that does not need a name.

Do I need a plain-text version of a personalized email?

Yes. A plain-text alternative that carries the same content and the same personalization as the HTML is expected by mail clients and filters, and some recipients read only that part. Render both parts from the same data in the same send, and check that conditions and fallbacks behave identically.

How do I support right-to-left languages such as Arabic or Hebrew?

Set the direction on the document or the relevant container, choose fonts that cover the script, and mark mixed content so that names, numbers and links in another script do not scramble the order. Test the actual rendering in the mail clients your audience uses, because direction handling differs between them.

How often should I review email templates?

Review every change before it goes live, and review the whole library on a schedule you choose, for example when brand, legal text, product names or data sources change. Old templates tend to hold stale links, outdated footers and variables that no longer exist.

Topics#email templates#personalization#merge variables#fallback values#header injection#html escaping#localization#right to left#subject line#plain text#template versioning#preview data
Was this guide helpful?Your answer helps us improve our documentation.

Keep reading

Sending and campaignsCAN-SPAM, CASL, PECR and Other Marketing Email Laws: A Plain-Language Overview for SendersEmail law differs by country, and the strictest rule that applies to a recipient is the one that matters. This overview compares the US CAN-SPAM Act, Canada CASL, UK PECR with UK GDPR, EU ePrivacy and GDPR, Australia Spam Act and the high-level picture in India, covering opt-in versus opt-out, identification, postal address, unsubscribe timing, B2B versus B2C, record keeping, a checklist and a worked example.Read guide →Sending and campaignsImporting an Existing Email List: Consent Evidence, Segmenting and Re-Permission CampaignsMoving an existing contact list to a new sending platform is the riskiest day in a sender history. This guide explains how to audit consent evidence and source, why purchased, rented and scraped lists hurt deliverability and create legal exposure, how to segment by recency, validate before import, stage the first sends, design a re-permission campaign, handle data you cannot justify and keep the records that prove it.Read guide →Sending and campaignsLifecycle Email Automation: Welcome Series, Onboarding, Cart and Re-engagement Flows That Protect DeliverabilityAutomated flows are some of the best-performing mail you send and some of the easiest to get wrong. This guide covers trigger design, cadence and throttling, exit and suppression rules, frequency caps across flows, keeping unconfirmed and bounced contacts out, transactional versus promotional content, flow-level monitoring, pre-launch QA, and a worked four-email welcome series.Read guide →

Start sending in minutes.

Create an account, add your domain and send your first email.

Start free Talk to sales