Phased GA: Content Decisioning is in phased general availability starting June 2026. Contact your Customer Success Manager (CSM) to confirm eligibility.
Content Variations let you test multiple versions of your message content and let the system automatically deliver more of what performs best.
This guide will walk you through how to write content variations with the vary() function and add them to your templates across email, SMS, and push.
Before you start: Your template must be a Liquid template — you select this when creating a new template. If your subject line or preview text shows the Liquid code itself instead of your content, you're on a legacy template and need to create a new Liquid template.
Step-by-Step: How to Set Up Content Variations
Step 1: Write Your Variation Code
Define variants with assign, then pass them to vary():
{%- assign SL1 = "Your weekend offer is here" -%}
{%- assign SL2 = "Don't miss your Friday bonus" -%}
{%- assign SL3 = "Exclusive: this week only" -%}
{{ vary([SL1, SL2, SL3]) }}
You can define 2, 3, or 4 variants per tag.
Whitespace Control
If you notice an unexpected blank space at the top of your subject line or preview text, add dashes to your assign tags to remove it. This is called dash syntax — {%- and -%} — and it trims whitespace around the tag.
Adding Personalization
Personalization can't go directly inside your list of variations. Build it as a separate variable first using the append filter, then include that variable in your variation list:
{%- assign name = customer.FIRST_NAME | default: "there" -%}
{%- assign SL1 = "Hey " | append: name | append: ", your offer is here" -%}
{%- assign SL2 = "Don't wait, " | append: name | append: " — offer ends Sunday" -%}
{{ vary([SL1, SL2]) }}
Use | default: "there" to handle missing attribute values.
When you use vary() across multiple fields, every tag must have the same number of variants. Variant 1 of the subject always sends with Variant 1 of the preview, and so on.
Correct — 3 variants in both fields:
{%- assign SL1 = "Your weekend offer is here" -%}
{%- assign SL2 = "Don't miss your Friday bonus" -%}
{%- assign SL3 = "Exclusive: this week only" -%}
{{ vary([SL1, SL2, SL3]) }}
{%- assign PV1 = "Open now to claim your reward." -%}
{%- assign PV2 = "Limited time — act before Sunday." -%}
{%- assign PV3 = "See what's waiting in your account." -%}
{{ vary([PV1, PV2, PV3]) }}
Mismatched counts trigger a validation error:
"All vary function calls must have the same number of items. Expected 2, found 3."
Build snippets faster with Optimove AI Chat. Describe what you need — for example, "Create four variations for my CTA button. The key action is getting customers at risk of churn to deposit," and it generates a ready-to-paste Liquid block. If varying multiple fields, mention that upfront, and it will generate matched blocks automatically.
Step 2: Insert into Your Template
The vary() syntax is the same across all channels. Where you paste it depends on the channel and the field.
Email
Subject line & preview text: Paste your full Liquid block directly into the field. These accept Liquid natively.
Body: For body variations, the Liquid is split into two parts.
Place your assign statements at the top of the template using dash syntax ({%- -%}) so they render invisibly:
{%- assign CTA1 = "Shop our weekend sale — up to 40% off everything." -%}
{%- assign CTA2 = "Your exclusive member discount is waiting inside." -%}
{%- assign CTA3 = "New arrivals just dropped. See what's trending." -%}
Place the vary() snippet into the specific body component you want to vary — for example, a CTA button, a headline, or a text block:
{{ vary([CTA1, CTA2, CTA3]) }}
This keeps your template clean — the variable definitions sit out of sight at the top, and only the short vary() snippet goes into the component you're varying.
SMS
Message text: Paste your Liquid block into the message text field in the SMS template editor.
Important: SMS variations require a tracked link in the message. Without a tracked link, the system has no way to measure which variant performs better.
Push Notifications
Title and/or body: Paste your Liquid block into the title field, the body field, or both. If varying both, the 1:1 rule applies — same number of variants in each field.
Note: At launch, vary() supports plain text strings only across all channels. Content blocks, data connections, and images are on the roadmap.
Step 3: Validate, Preview, and Test
Instructions:
Validate. The Template Editor checks for errors automatically when you save. If the number of variations doesn't match across fields, you'll see: "All vary function calls must have the same number of items." Fix it by making sure every field uses the same variation count.
Preview. Click Preview in the Template Editor. Each refresh shows a different variation — cycle through them to check all versions. A dropdown to select a specific variation is coming in a future update.
Test Send. Use test send to check rendering in an actual inbox. Test sends will show one of the variations at random.
If personalization tags aren't rendering, check for a syntax error in your assign statements or confirm you're on a Liquid template.
Constraints at Launch
Template must be Liquid (not legacy).
2–4 variants per vary() tag.
All vary() tags in a template must have the same number of variants (validated at save).
Plain text strings only inside vary() — no content blocks, data connections, or images yet.
SMS requires a tracked link for optimization to work.
Do not mix legacy Subject Line Test and Liquid vary() on the same campaign — create a new campaign.