Customer.io Liquid Tutorial: Dynamic Email Personalisation Without Writing Code
When Champollion Cracked the Code Nobody Else Could Read
On September 27, 1822, a 31-year-old French scholar named Jean-François Champollion rushed into his brother's office in Paris and shouted "Je tiens l'affaire!" — "I've got it!" — before collapsing to the floor in exhaustion. He had just deciphered Egyptian hieroglyphics, a writing system that had been unreadable for nearly 1,400 years.
The key was the Rosetta Stone. Discovered by Napoleon's soldiers in 1799, it contained the same decree written in three scripts: hieroglyphics, Demotic, and Ancient Greek. Scholars already understood Greek. The breakthrough was realising that hieroglyphics weren't just pictures — they were a mix of phonetic sounds and symbolic meaning. Once Champollion understood the system, he could read any inscription in any Egyptian temple.
He didn't need to learn a new language. He needed a translation layer between what he already understood and what he wanted to say.
That's exactly what Liquid is for your marketing emails.
Liquid is the templating language that sits between your customer data and your email content. You already have the data — names, plans, purchase history, behaviour. Liquid is the translation layer that turns that data into dynamic, personalised messages. And just like Champollion didn't need to become Egyptian to read hieroglyphics, you don't need to become a developer to use Liquid.
According to Customer.io's State of Messaging Report, 81% of brands find personalisation important to their messaging strategy. Research from Instapage shows personalised emails achieve 29% higher open rates and 41% higher click-through rates than generic ones. And Forbes reports that personalised emails generate 6x higher transaction rates.
This tutorial teaches you every Liquid technique you need to create those results. Every example is copy-paste ready for Customer.io.
What Is Liquid and How Does It Work in Customer.io?
Liquid is an open-source templating language originally created by Shopify. Customer.io uses Liquid to let you insert dynamic content into emails, SMS, push notifications, and in-app messages.
Here's the core concept: you write a template with placeholders. When Customer.io sends the message, it replaces those placeholders with real data for each recipient.
Liquid has three building blocks:
Keys (also called objects) are placeholders wrapped in double curly braces. They pull in data.
{{ customer.first_name }}
Filters modify the output of keys. They come after a pipe character |.
{{ customer.first_name | capitalize }}
Tags add logic — if/else conditions, loops, assignments. They use curly braces with percent signs.
{% if customer.plan == "premium" %}
You're a Premium member!
{% endif %}
That's it. Three concepts. Everything in this tutorial builds on those three things.
How Do You Add a Personal Greeting with a Fallback?
This is your first Liquid pattern and the most important one. Always include a fallback.
If a recipient doesn't have the attribute you reference, the message will fail to send. That means zero delivery — not a blank space, not a broken tag, but a complete failure. Fallbacks prevent this.
The Simple Way (Latest Liquid)
Hi {{ customer.first_name | default: "there" }},
If the customer has a first_name of "Sarah", they see: Hi Sarah,
If the customer has no first_name, they see: Hi there,
The default filter is only available on Customer.io's latest Liquid version. Check your version in Settings > Workspace Settings.
The Universal Way (Works on All Versions)
Hi {% if customer.first_name %}{{ customer.first_name | capitalize }}{% else %}there{% endif %},
This works on both legacy and latest Liquid. Use it if you're not sure which version you're on.
Extracting First Name from a Full Name Field
Some systems store a single full_name instead of separate first and last names. Split it:
Hi {{ customer.full_name | split: " " | first | default: "there" }},
This takes "Sarah Johnson", splits it at the space, grabs the first word ("Sarah"), and falls back to "there" if the field is empty.
How Do You Show Different Content Based on User Attributes?
Conditional content is where Liquid becomes genuinely powerful. You write one email template that delivers different content to different people.
Basic If/Else: Segment by Plan Type
{% if customer.plan == "enterprise" %}
As an Enterprise customer, you have access to dedicated support.
Book a call with your account manager: {{ customer.account_manager | default: "our team" }}.
{% elsif customer.plan == "pro" %}
You're on the Pro plan — great choice.
Upgrade to Enterprise for dedicated support and custom integrations.
{% elsif customer.plan == "starter" %}
Welcome to Starter! Here are three features to try this week.
{% else %}
Start your free trial today and see what you've been missing.
{% endif %}
One email. Four completely different experiences. No separate campaigns needed.
Conditional Content Based on Behaviour
Show different content based on what users have or haven't done:
{% if customer.completed_onboarding == true %}
You've finished setup — let's talk about advanced features.
{% else %}
You're almost there! Complete these last {{ customer.onboarding_steps_remaining | default: "few" }} steps to unlock the full experience.
{% endif %}
This is the foundation of behaviour-triggered journeys — sending the right message based on actual actions, not arbitrary timelines.
Using case/when for Multiple Conditions
When you have more than three or four options, case statements are cleaner than nested if/elsif chains:
{% case customer.industry %}
{% when "saas" %}
Here's how SaaS companies use our platform to reduce churn.
{% when "ecommerce" %}
See how online retailers boost repeat purchases.
{% when "fintech" %}
Learn how financial services stay compliant while personalising.
{% when "healthcare" %}
Discover HIPAA-friendly engagement strategies.
{% else %}
See how companies like yours get results.
{% endcase %}
Combining Multiple Conditions
Use and / or to check several things at once:
{% if customer.plan == "enterprise" and customer.days_since_last_login > 30 %}
We noticed you haven't logged in recently. Your account manager
{{ customer.account_manager | default: "would love" }} to help
you get back on track.
{% endif %}
{% if customer.role == "admin" or customer.role == "owner" %}
As a team leader, here are your team's engagement stats this month.
{% endif %}
How Do You Create Dynamic CTAs Based on User Attributes?
Static call-to-action buttons waste conversions. Someone on a free plan should see "Upgrade Now." Someone on a paid plan should see "Explore Advanced Features." Liquid makes this effortless.
Dynamic Button Text
{% if customer.plan == "free" %}
<a href="https://app.example.com/upgrade">Start Your Free Trial</a>
{% elsif customer.plan == "trial" %}
<a href="https://app.example.com/subscribe">Subscribe Before Your Trial Ends</a>
{% elsif customer.plan == "starter" %}
<a href="https://app.example.com/upgrade?plan=pro">Upgrade to Pro</a>
{% else %}
<a href="https://app.example.com/dashboard">Go to Your Dashboard</a>
{% endif %}
Dynamic URLs with Customer Attributes
Personalise the link destination itself:
<a href="https://app.example.com/dashboard?user={{ customer.id }}&ref=email">
Open Your Dashboard
</a>
Urgency-Based CTAs
Combine date logic with CTAs for time-sensitive messaging:
{% assign current_date = 'now' | date: '%s' %}
{% assign trial_end = customer.trial_end_date %}
{% assign days_left = trial_end | minus: current_date | divided_by: 86400 %}
{% if days_left <= 3 and days_left > 0 %}
<a href="https://app.example.com/subscribe">
Only {{ days_left }} day{% if days_left != 1 %}s{% endif %} left — Subscribe Now
</a>
{% elsif days_left <= 7 %}
<a href="https://app.example.com/pricing">
Your trial ends in {{ days_left }} days — See Plans
</a>
{% else %}
<a href="https://app.example.com/features">
Explore What's Possible
</a>
{% endif %}
The 86400 number is the number of seconds in a day. Dividing the difference between two epoch timestamps by 86400 gives you the number of days between them.
How Do You Build Personalised Product Recommendations?
If you store purchase or browsing data in Customer.io, you can build personalised product sections directly in your emails.
Looping Through a Product Array
Suppose you track a customer's recently viewed products as an attribute:
{% if customer.recently_viewed.size > 0 %}
<h3>Pick up where you left off</h3>
{% for product in customer.recently_viewed limit: 3 %}
<div>
<strong>{{ product.name }}</strong><br>
${{ product.price }}<br>
<a href="{{ product.url }}">View Product</a>
</div>
{% endfor %}
{% else %}
<h3>Trending this week</h3>
<p>Check out what other customers are loving right now.</p>
<a href="https://shop.example.com/trending">See Trending Products</a>
{% endif %}
The limit: 3 keeps the email concise. The else block ensures everyone sees something, even without browsing history.
Event-Triggered Product Recommendations
When a purchase event triggers a campaign, use event data to reference what they bought and recommend related items:
Thanks for ordering {{ event.product_name | default: "your item" }}!
{% if event.category == "running" %}
Customers who bought running shoes also love:
- Performance running socks
- Hydration belts
- Reflective gear
{% elsif event.category == "yoga" %}
Complete your yoga setup:
- Premium yoga mat
- Cork yoga blocks
- Organic mat cleaner
{% else %}
Check out our bestsellers:
<a href="https://shop.example.com/bestsellers">Shop Now</a>
{% endif %}
Dynamic Pricing and Discounts
Tailor the offer based on customer lifetime value:
{% assign ltv = customer.lifetime_value | plus: 0 %}
{% if ltv > 500 %}
As a VIP customer, enjoy 25% off your next order: VIP25
{% elsif ltv > 100 %}
Here's 15% off as a thank you: THANKS15
{% else %}
Welcome! Enjoy 10% off your first order: WELCOME10
{% endif %}
Note the | plus: 0 trick. Customer.io stores attributes as strings. Adding zero converts the string to a number so comparisons work correctly. Without this, "500" > "100" might not evaluate as you'd expect.
How Do You Handle Dates and Timestamps?
Dates are one of the trickiest parts of Liquid because Customer.io stores them as Unix timestamps (seconds since January 1, 1970). Here's how to make them human-readable.
Display a Readable Date
{{ customer.created_at | date: "%B %-d, %Y" }}
Turns 1709913600 into March 8, 2024.
Common Date Format Codes
| Code | Output | Example |
|---|---|---|
%B |
Full month name | March |
%b |
Abbreviated month | Mar |
%d |
Day (zero-padded) | 08 |
%-d |
Day (no padding) | 8 |
%m |
Month number | 03 |
%Y |
Four-digit year | 2024 |
%y |
Two-digit year | 24 |
%H |
Hour (24-hour) | 14 |
%I |
Hour (12-hour) | 02 |
%M |
Minute | 30 |
%p |
AM/PM | PM |
%A |
Day of week | Friday |
Calculate Days Until an Event
{% assign now = 'now' | date: '%s' %}
{% assign event_date = customer.renewal_date %}
{% assign days_until = event_date | minus: now | divided_by: 86400 %}
Your subscription renews in {{ days_until }} days.
Show Current Year (for Copyright Footers)
© {{ 'now' | date: "%Y" }} Your Company. All rights reserved.
Show Different Content by Day of Week
{% assign today = 'now' | date: '%A' %}
{% if today == 'Friday' %}
Happy Friday! Here's your weekend reading list.
{% elsif today == 'Monday' %}
New week, new opportunities. Here's what's ahead.
{% else %}
Here's what's new today.
{% endif %}
How Do You Use Loops for Lists and Collections?
Loops let you iterate over arrays of data — perfect for order summaries, feature lists, or any repeated content.
Basic Loop: Order Confirmation
Here's your order summary:
{% for item in event.items %}
{{ item.name }} — ${{ item.price }}
{% endfor %}
Total: ${{ event.total }}
Loop with Index Numbers
Your top 3 recommended actions:
{% for action in customer.recommended_actions limit: 3 %}
{{ forloop.index }}. {{ action.title }}
{% endfor %}
forloop.index gives you 1, 2, 3. Use forloop.index0 if you want 0, 1, 2.
Sorting Looped Data
Sort items before displaying them (requires latest Liquid):
{% assign sorted_items = event.items | sort: 'price' | reverse %}
{% for item in sorted_items %}
{{ item.name }} — ${{ item.price }}
{% endfor %}
This displays items from highest to lowest price.
Grouping and Sorting
For more complex data, group items by category then sort within each group:
{% assign groups = customer.purchases | group_by: "category" | sort: 'name' %}
{% for group in groups %}
<h4>{{ group.name | capitalize }}</h4>
{% assign sorted_items = group.items | sort: 'title' %}
{% for item in sorted_items %}
- {{ item.title }}
{% endfor %}
{% endfor %}
How Do You Personalise Subject Lines with Liquid?
Liquid works everywhere in Customer.io — including subject lines and preview text. This is where personalisation has the highest impact on open rates.
Name in Subject Line
{{ customer.first_name | default: "Hey" }}, your weekly report is ready
Urgency in Subject Line
{% assign days = customer.trial_days_remaining | plus: 0 %}
{% if days <= 3 %}⚠️ {{ days }} days left on your trial{% else %}Your trial update{% endif %}
Personalised Preview Text
Use the same Liquid patterns in your preview text field:
{{ customer.first_name | default: "Hi there" }} — we noticed you haven't tried {{ customer.unused_feature | default: "our newest feature" }} yet.
For guidance on A/B testing these personalised subject lines, check our onboarding email sequences guide which covers testing strategies in detail.
How Do You Use Liquid for Localisation?
Serving a global audience? Liquid can adapt language, currency, and date formats based on each user's locale.
Language-Based Content
{% if customer.language == "es" %}
¡Hola {{ customer.first_name | default: "amigo" }}!
Gracias por ser parte de nuestra comunidad.
{% elsif customer.language == "fr" %}
Bonjour {{ customer.first_name | default: "ami" }} !
Merci de faire partie de notre communauté.
{% elsif customer.language == "de" %}
Hallo {{ customer.first_name | default: "Freund" }}!
Danke, dass du Teil unserer Community bist.
{% else %}
Hey {{ customer.first_name | default: "there" }}!
Thanks for being part of our community.
{% endif %}
Currency Formatting
{% if customer.currency == "GBP" %}
Your balance: £{{ customer.balance }}
{% elsif customer.currency == "EUR" %}
Your balance: €{{ customer.balance }}
{% else %}
Your balance: ${{ customer.balance }}
{% endif %}
Localised Date Formatting
Different regions expect different date formats:
{% if customer.country == "US" %}
{{ customer.renewal_date | date: "%m/%d/%Y" }}
{% elsif customer.country == "GB" %}
{{ customer.renewal_date | date: "%d/%m/%Y" }}
{% else %}
{{ customer.renewal_date | date: "%Y-%m-%d" }}
{% endif %}
What Are the Most Common Liquid Mistakes (and How Do You Fix Them)?
Mistake 1: No Fallback Values
Problem: Message fails to send because an attribute is missing.
Fix: Always add a fallback. Use | default: "value" (latest Liquid) or wrap in {% if %}{% else %}{% endif %} (all versions).
Mistake 2: Comparing Numbers Stored as Strings
Problem: {% if customer.age > 30 %} doesn't work because age is stored as a string.
Fix: Convert to a number first with | plus: 0:
{% assign age = customer.age | plus: 0 %}
{% if age > 30 %}
Content for over 30
{% endif %}
Mistake 3: Forgetting endif, endfor, or endcase
Problem: Liquid throws an error because a tag was never closed.
Fix: Every {% if %} needs {% endif %}. Every {% for %} needs {% endfor %}. Every {% case %} needs {% endcase %}. Count your opening and closing tags.
Mistake 4: Using > or < in the Drag-and-Drop Editor
Problem: Comparison operators get interpreted as HTML tags in the drag-and-drop editor.
Fix: Use the Add Liquid button in text blocks when writing conditions with >, <, or &. This tells the editor to treat the content as Liquid, not HTML.
Mistake 5: Referencing Event Data Outside an Event-Triggered Campaign
Problem: {{ event.product_name }} renders blank.
Fix: The event object only works in event-triggered campaigns. For other campaign types, use {{ trigger.product_name }} for transactional/API-triggered messages, or {{ customer.attribute }} for person attributes.
How Do You Test Liquid Before Sending?
Never send untested Liquid to your audience. Customer.io gives you tools to verify everything works.
Step 1: Use the Preview Panel
When editing a message, open the preview panel and search for a specific person. Customer.io replaces all Liquid with that person's real data. Test with several different profiles — especially ones with missing attributes — to verify your fallbacks work.
Step 2: Send Test Emails
Use Customer.io's Send Test feature to deliver the email to yourself with a specific person's data. Check every conditional branch.
Step 3: Create Test Profiles
Make a few test profiles with deliberately incomplete data:
- One with all attributes filled
- One with only email (bare minimum)
- One with edge cases (long names, special characters, zero values)
Step 4: Check Delivery Logs
After sending, review the Activity Log for any person who received the message. It shows exactly what Liquid rendered. Failed deliveries show which Liquid statement caused the failure.
For comprehensive measurement of how your personalised campaigns perform, see our lifecycle marketing reporting and attribution guide.
Complete Example: A Fully Personalised Email
Here's everything pulled together in a single email template you can use as a starting point:
Subject: {{ customer.first_name | default: "Hey" }}, your {{ customer.plan | default: "monthly" }} update is here
---
Hi {{ customer.first_name | default: "there" }},
{% if customer.days_as_customer | plus: 0 > 365 %}
Happy anniversary! You've been with us for over a year. 🎉
{% elsif customer.days_as_customer | plus: 0 > 30 %}
Great to have you on board.
{% else %}
Welcome! We're glad you're here.
{% endif %}
Here's what happened this month:
{% if customer.monthly_usage | plus: 0 > 0 %}
- You used {{ customer.feature_name | default: "our tools" }} **{{ customer.monthly_usage }}** times
- That's {% if customer.usage_change | plus: 0 > 0 %}{{ customer.usage_change }}% more{% else %}about the same{% endif %} as last month
{% else %}
- We didn't see much activity this month. Need help getting started?
{% endif %}
{% case customer.plan %}
{% when "free" %}
**Ready to unlock more?**
Upgrade to Pro and get unlimited access.
[See Pro Plans](https://app.example.com/upgrade)
{% when "pro" %}
**Get even more value**
Enterprise customers get dedicated support and custom integrations.
[Learn About Enterprise](https://app.example.com/enterprise)
{% when "enterprise" %}
**Your dedicated account manager**
{{ customer.account_manager | default: "Our team" }} is here to help.
[Book a Call](https://app.example.com/book-call)
{% endcase %}
Cheers,
The Team
© {{ 'now' | date: "%Y" }} Example Company
This one template serves every customer differently — free users get upgrade prompts, enterprise users get account manager info, new users get welcomed, and veterans get celebrated. One template. Infinite variations.
Quick Reference: Essential Liquid Patterns
| What You Want | Liquid Code |
|---|---|
| Customer name with fallback | {{ customer.first_name | default: "there" }} |
| Capitalise a name | {{ customer.first_name | capitalize }} |
| Show/hide content | {% if customer.plan == "pro" %}...{% endif %} |
| If/else branching | {% if condition %}A{% else %}B{% endif %} |
| Multiple options | {% case customer.role %}{% when "admin" %}...{% endcase %} |
| Loop through items | {% for item in event.items %}{{ item.name }}{% endfor %} |
| Limit loop iterations | {% for item in list limit: 3 %}...{% endfor %} |
| Convert string to number | {% assign num = customer.val | plus: 0 %} |
| Format a date | {{ customer.date | date: "%B %-d, %Y" }} |
| Current date/year | {{ 'now' | date: "%Y" }} |
| Split a full name | {{ customer.name | split: " " | first }} |
| Dynamic link | <a href="https://app.com/{{ customer.id }}">Link</a> |
| Assign a variable | {% assign greeting = "Hello" %} |
Frequently Asked Questions About Customer.io Liquid
What is Liquid in Customer.io?
Liquid is a templating language that lets you insert dynamic, personalised content into Customer.io messages. It uses three building blocks: keys (placeholders like {{ customer.first_name }}), filters (modifiers like | capitalize), and tags (logic like {% if %}...{% endif %}). When Customer.io sends a message, it replaces Liquid placeholders with real data for each recipient. Liquid works in emails, SMS, push notifications, subject lines, preview text, and in-app messages.
Do I need to know how to code to use Liquid?
No. Liquid is designed to be readable by non-developers. If you can understand "if the customer's plan is free, show an upgrade button" — you can write Liquid. The syntax is plain English with some curly braces and percentage signs. Start with simple name personalisation and build up to conditional content as you get comfortable. Customer.io also offers a point-and-click interface for inserting basic Liquid in their rich text editor.
What happens if a customer is missing an attribute I reference?
The message fails to send entirely. It doesn't show a blank space or a broken tag — it fails delivery. This is why fallback values are mandatory. Use the default filter ({{ customer.name | default: "friend" }}) or if/else statements to provide alternative content. Always test with profiles that have missing attributes before launching a campaign.
What's the difference between customer, event, trigger, and journey objects?
The customer object references attributes stored on a person's profile (name, plan, signup date) and works in any message. The event object references data from the event that triggered an event-triggered campaign. The trigger object references payload data in transactional messages, API-triggered broadcasts, and webhook-triggered campaigns. The journey object references temporary attributes set during a campaign workflow via webhook actions or the Set Journey Attributes action. Each has a specific context where it works.
Can I use Liquid in email subject lines?
Yes. Liquid works in subject lines, preview text, sender name, and any other field in Customer.io — not just the email body. Personalised subject lines are one of the highest-impact uses of Liquid. Research shows personalised subject lines increase open rates by 26%. Just remember to include fallbacks, because a failed Liquid expression in a subject line will prevent the entire message from sending.
How do I compare numbers in Liquid?
Customer.io stores all attributes as strings, even numbers. Before comparing, convert the string to a number by adding zero: {% assign value = customer.score | plus: 0 %}. Then use comparison operators: {% if value > 50 %}. Without the conversion, string comparison rules apply — where "9" is greater than "50" because "9" comes after "5" alphabetically.
What's the difference between legacy and latest Liquid in Customer.io?
Customer.io has two Liquid versions. The latest version supports the default filter, better error handling, and additional filters like group_by and sort. Legacy Liquid requires if/else statements for fallbacks instead of the default filter. Check your version under Settings > Workspace Settings. Most new workspaces use the latest version. You can upgrade, but test all existing messages after upgrading since some behaviour differences exist.
How do I loop through a list of items in Liquid?
Use a for loop: {% for item in customer.items %}{{ item.name }}{% endfor %}. You can limit iterations with limit: 3, access the current index with forloop.index, and check if you're on the first or last item with forloop.first and forloop.last. Loops work with any array-type attribute or event property — product lists, feature arrays, tag collections, and more.
Can I use Liquid to show different content to different customer segments?
Yes. Use conditional tags (if, elsif, else, case/when) to branch content based on any customer attribute. You can check plan type, role, industry, country, behaviour flags, numeric thresholds, or any custom attribute you track. This lets one email template serve multiple segments with different messaging, CTAs, and offers — reducing the number of separate campaigns you need to manage.
How do I personalise content based on event data like a purchase?
In an event-triggered campaign, use the event object to reference properties from the triggering event. For example, {{ event.product_name }} pulls in the product from a purchase event. You can combine this with conditional logic to show different recommendations based on product category, price, or any other event property. Remember: event data only works in the campaign triggered by that specific event.
How do I handle dates and timestamps in Liquid?
Customer.io stores dates as Unix timestamps (seconds since January 1, 1970). Use the date filter to format them: {{ customer.signup_date | date: "%B %-d, %Y" }} renders as "March 8, 2024". For the current date, use {{ 'now' | date: "%Y-%m-%d" }}. To calculate the difference between dates, convert both to seconds with | date: '%s', subtract, then divide by 86400 for days.
How do I test Liquid before sending emails?
Use Customer.io's preview panel to search for specific people and see how Liquid renders with their data. Send test emails to yourself using different customer profiles. Create test profiles with deliberately missing attributes to verify fallbacks. After sending, check the Activity Log for any recipient to see exactly what content was rendered. Never launch a campaign with untested Liquid — one missing fallback can cause mass delivery failures.
Can I nest Liquid conditions inside each other?
Yes. You can nest if statements inside other if statements, and put conditionals inside loops. For example, you might loop through products and only display those above a certain price, or check a customer's plan inside a condition that already checks their country. Keep nesting shallow (two or three levels maximum) for readability. If your Liquid gets deeply nested, consider whether separate campaigns or segments would be cleaner.
What are journey attributes and when should I use them?
Journey attributes are temporary data you set during a campaign workflow — typically from webhook responses. They exist only for the duration of that person's journey through the campaign. Use them when you need external data (weather, inventory, real-time pricing) in your messages without permanently storing it on a customer profile. Reference them with {{ journey.attribute_name }}. They keep your workspace data clean by not cluttering customer profiles with transient information.
The Bottom Line
Champollion spent years learning the system that unlocked Egyptian hieroglyphics. You can learn the system that unlocks personalised email in an afternoon.
Liquid isn't code. It's a translation layer between your customer data and the messages you want to send. Every example in this tutorial is copy-paste ready. Start with a name and a fallback. Then add a conditional. Then try a loop. Before you know it, you'll be writing single templates that serve every customer differently.
The data backs up the effort. Personalised emails generate 6x higher transaction rates, 29% higher open rates, and 41% higher click-through rates. And with only 10% of companies fully automating their customer journeys, there's a massive competitive advantage waiting for teams who master this skill.
Your next step: open your most-sent email in Customer.io. Add one {{ customer.first_name | default: "there" }}. Preview it. Send a test. Then come back here and try conditional content.
If you want help building personalised email campaigns that convert — or turning Customer.io into a revenue-generating machine — get in touch with NerveCentral. As a Customer.io Certified Partner, we build the Liquid-powered automations that make every message feel like it was written just for the person reading it.
About NerveCentral
NerveCentral is a Customer.io Certified Partner. We craft digital marketing campaigns that engage and convert your customers. We help businesses turn Customer.io into a revenue-generating machine with better emails, smarter automations, more conversions, and less churn.
Sources & Citations
-
Smithsonian Magazine. (2022). "What Is the Rosetta Stone?" Smithsonian Magazine.
-
Customer.io. (2024). "An Introduction to the Liquid Template Language." Customer.io Learn.
-
Customer.io. (2026). "Personalize messages with Liquid." Customer.io Documentation.
-
Customer.io. (2025). "Liquid recipes." Customer.io Documentation.
-
Forbes Advisor. (2024). "49 Top Email Marketing Statistics." Forbes.
-
Instapage. (2025). "70 Personalization Statistics Every Marketer Should Know in 2025." Instapage Blog.
-
EmailVendorSelection. (2025). "39+ Major Marketing Automation Statistics to Know in 2026." EmailVendorSelection.


