On this page

Every {{n}} variable in an approved template must be mapped to something before a broadcast can send: a contact field, a custom field, static text, or a tracked link, each with a mandatory fallback so a missing value never breaks the send. This article explains how the mapping works, what each variable source does, and why a fallback is required even for values you expect to always be present.
Variables and fallbacks: first 5 of 6 steps
- 1Pick a template on the Message step
- 2Choose a source for each variable
- 3Enter a fallback for every non-static source
- 4Fill in static text where the value
- 5Check the live preview
Before you start
- You need an approved template with at least one
{{n}}variable. See template builder components if you have not built one yet. - If you plan to personalize with a custom field (loyalty tier, membership number, a booking date), that field needs to exist under Contacts first.
- Understand which contacts actually have the field populated. A variable mapped to email personalizes nothing useful if half your contacts have no email on file, though the fallback still keeps the send working.
Steps
- Pick a template on the Message step. Once you select an approved template that has variables, a Personalization panel appears listing every
{{n}}the template needs, split into header, body and button rows where applicable.

Choose a source for each variable. For every row, pick one of: Contact name, Contact phone, Contact email, Custom field (then pick which one), Static text (then type the exact value), or Tracked link (only available once you have set a "Track clicks to" URL). A body variable, a header text variable and a button link variable are each mapped independently, even if they logically represent the same idea.
Enter a fallback for every non-static source. Each row that is not static text requires a fallback value: what sends if that specific contact's field is empty. This is mandatory, the composer will not let you continue without it, because a missing value in even one recipient's field must never produce a message with the wrong number of parameters.
Fill in static text where the value is the same for everyone. A coupon code, a campaign name, or any detail that does not vary by recipient goes here as literal text rather than being mapped to a contact field with an identical fallback for every row.
Check the live preview. As you complete the mapping, the composer's preview panel renders the message with real values, so you can see exactly what a contact with a populated field looks like, and, on the Review & Send step, exactly what a contact relying on the fallback looks like too.
Handle header, media and button fields separately. A media header (image, video or document) is set once for the whole campaign in its own field above the personalization rows, not per recipient. A URL button whose link contains a variable gets its own "Button link" row in the personalization panel.
How does the fallback actually get chosen at send time?
Each recipient's value is resolved individually at the moment their message is built, not when you set up the campaign. For a contact-field or custom-field variable, the resolver checks the contact's actual value first; if that value is missing or blank after trimming whitespace, it uses your fallback instead. For a static-text variable, every recipient simply gets the text you typed. This resolution happens per recipient inside the send loop, so two contacts with the same template can receive genuinely different personalized text in the same campaign, one from their real name, another from the fallback, without either one failing.
This also protects templates with other component types. A document header attachment uses the template's own name (for example "Monthly Report") rather than the uploaded file's raw filename, so a recipient does not see an attachment literally called "header.pdf." A template with a limited-time offer badge gets its countdown calculated fresh for each send, starting from the moment the message actually reaches Meta rather than from a fixed campaign-wide clock, so a recipient who receives the message an hour into a long send still sees the full offer window from their own perspective.
Example
A real-estate agency sends a new-listing alert mapping {{1}} to the contact's name and {{2}} to a custom field, "preferred locality." Eighty percent of contacts have a locality on file and see it by name; the remaining twenty percent, where the field was never filled in, see the fallback text "your preferred area" instead, and the send completes successfully for all of them.
What you will see
The Personalization panel lists one row per variable with a dropdown for the source and, for most sources, a text field for the fallback. A variable with no source chosen, or a non-static source with an empty fallback, blocks the Continue button and the final Send. The preview on the Message step and the Review & Send step both render against real contact data, so you see the actual rendered message, not a placeholder like "{{1}}."
What about templates with a header, a coupon code, or a location pin?
Not every template component is a per-recipient variable. A media header (image, video or document) and a "copy offer code" button carry one value for the whole campaign, set once in their own field on the Message step above the Personalization panel, since one campaign is one creative sent to everyone, the same logic a normal marketing email or SMS blast already follows. A location header works the same way: one pin, with a name and address, for the entire send, because a template offering "our clinic's location" only makes sense as a single fixed place, not something that varies by recipient the way a name or a balance does.
This distinction keeps the Personalization panel focused on what genuinely needs to vary by contact and keeps campaign-wide details, a coupon code, a banner image, a shop's address, in one obvious place instead of forcing you to map the same static value to every recipient as if it were personal data.
Settings and options
| Variable source | What it sends | Fallback required |
|---|---|---|
| Contact name | The contact's stored name | Yes |
| Contact phone | The contact's stored phone number | Yes |
| Contact email | The contact's stored email address | Yes |
| Custom field | The value of a chosen custom field on that contact | Yes |
| Static text | The exact text you type, identical for every recipient | No (the text itself is required) |
| Tracked link | A per-recipient signed link to the "Track clicks to" URL | Not applicable |
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| "Variable {{n}} is not mapped" error on Continue | A variable in the template body has no row filled in | Scroll to the Personalization panel and fill in every listed variable |
| "A fallback value is required" error | A non-static variable's fallback field is empty | Enter a fallback; it only needs to make sense in the rare case the mapped field is empty |
| Everyone receives the same value for a variable that should be personalized | The variable is mapped to Static text instead of a contact or custom field | Change the source to the correct contact or custom field |
| Message preview shows the fallback for most recipients | The mapped contact or custom field is empty for most of the audience | Check whether that field is actually populated on your contacts; consider a different field or importing the data first |
| Tracked link option is missing from the source dropdown | No URL has been entered in "Track clicks to" yet | Enter a URL there first; the Tracked link source appears once it exists |
Related reading
Once variables are mapped correctly, check the exact cost and send a test message before launching, in cost estimate and test send, or go back to building the audience if you have not finished that step.