Personalizing Your Messages With Liquid

With, you can use the Liquid templating language to personalize your emails. Any part of the email or layout can contain Liquid, including the subject line, from address, headers, etc.

The basics: customer attributes

If you want to include a customer’s attribute in your email, you’ll want to include a liquid tag that references that attribute. For example, if you have a field first_name, the tag would be:

{{ customer.first_name }}

Anything you’ve included as a customer attribute should start with customer. before your attribute name.

Using event data

Let’s use a simple example for a user who bought a pair of socks, amd you want to send a receipt for those socks. To do that, you send a purchase event, with attached data for the socks they bought, and how much those socks cost. Say the data that received looks like this (Javascript):

_cio.track("purchase", { price: "23.45", product: "socks" });

You could then access that data in your email text like this:

You just bought {{ event.product }} for {{ event.price }}!

That would output “You just bought socks for 23.45!” You’ll see that though the event is named “purchase”, you still use the notation event to reference it in

Note that event data is only accessible in event triggered campaigns

If you need more detailed technical information about sending events, it’s in our API docs.

Filters and tags

Filters and tags make up the foundations of Liquid, and there are a number of them that you can use. In the first-name example, if you wanted to make sure it was capitalized, add a capitalize filter to the tag:

{{ customer.first_name | capitalize }}

If the field was full_name and you wanted to include only the first word/name, you could use:

{{ customer.full_name | split: " " | first }}

Check out the other filters and tags (and how to write them) in our complete Liquid documentation.

More examples: what else can you do?


If only a subset of your users have the specific attribute you want to include, you’ll want to only use that tag for matching users and set up a fallback otherwise.

{% if customer.first_name != blank %}
  {{ customer.first_name | capitalize }}
{% else %}
{% endif %}

You can include attributes within links as well, in order to send your users to a custom page.


<a href="{{customer.ATTRIBUTE}}">

Displaying a timestamp as a regular date

Let’s say you have a customer attribute called expiration that you store as a timestamp. If you wanted to display that expiration date in emails as a regular date, you can do so with liquid. There are a few different filters you can use with this, but for examples sake we’re just going to show you month name, day, and year.


If you had a customer attribute called expiration with a value of 1394922570 if you include in your template:

{{customer.expiration| date: "%B %-d, %Y"}}

The result in your email would be March 15, 2014

The spaces, commas, etc between the date filters are included in the output. So if you want 11/04/2014 you’d do %m/%d/%Y.

For the current date, you can use:

{{ 'now' | date: "%B %-d, %Y" }}

Converting from USD to GBP

{{ "9" | divided_by: 2.00 | currency | replace:"$", "£" }}

Displaying how many days left in a trial

{% assign current_date = 'now' | date: '%s' %}
{% assign future_date = customer.trial_end %}
{{ future_date | minus: current_date | divided_by: 86400 }}


  1. You can get the current epoch time with 'now' | date: "%s". %s is a formatting option.
  2. The customer.trial_end date is in epoch time.
  3. Since epoch time is in seconds, we’re dividing by 86400 (number of seconds in a day) to get the number of days. Keep in mind that this is integer division so it’ll be rounded down.

Compare two user or event attributes

While it’s not possible to compare attributes when you create segments or when you set up an event filter for your campaign, you can use liquid code inside your campaign’s content to achieve this purpose.

{% if customer.attribute_1 == customer.attribute_2 %} 
	Hello awesome person! 
{% endif %}

If you want to show the customer’s name along with their email address in the To field:

{{}} <{{}}>

The result will be: “ Support”

Localizing date

If you want to display the month in your customers’ language:

{{ event.invoice_date | date: "%-d" }}
{% case m %}
{% when '1' %}janvier
{% when '2' %}février
{% when '3' %}mаrs
{% when '4' %}avril
{% when '5' %}mаi
{% when '6' %}Juin
{% when '7' %}juillet
{% when '8' %}août
{% when '9' %}septembre
{% when '10' %}octobre
{% when '11' %}novembre
{% when '12' %}décembre
{% endcase %}
{{ event.invoice_date | date: "%Y" }}

Show a different message based on day of week

{% assign day = 'now' | date: '%A' %}
{% if day == 'Friday' %}
Have a great weekend!
{% else %}
{% endif %}

Dealing with whitespace

We recommend adding data to without spaces. But if you do, you can reference attributes like:

{{ customer["white space"] }}

Filtering out default data or specific data

{% if customer.first_name contains 'Visitor' %}
	{% else %}{{ customer.first_name | capitalize }}
{% endif %}

Advanced: Loops!

Looping through attributes

Say you’re a microblogging platform. As part of their data, each customer has a list of “similar people”, and you want to include this list in an email.

Here’s an example of what the data you send to might look like in Javascript:

  id:               "1",
  similar_people:   [ "Elaine", "George", "Kramer"]

Say the user with an id of 1 is Jerry Seinfeld. Then, when you’re composing your messages to him, you can you can loop through the similar people in the email using a Liquid for loop:

{% for person in customer.similar_people %}
  {{ person }}<br/>
{% endfor %}

And that’s it! That’ll display:

Elaine George Kramer

Looping through event data

Let’s go back to our event data example above. Instead of making one purchase (socks), let’s say a customer bought multiple items (socks, toothpaste, and dental floss), and you want to list them all in your receipt email. If you sent us data like this (this example’s in Ruby):

customerio.track ( user_id, "purchase",
 :items => [
    {:name => "socks", :price => "23.45"},
    {:name => "toothpaste", :price => "3"},
    {:name => "dental floss", :price => "2.97"}

You can access that data to output a list by looping through it. This is how you’d do that:

{% for item in event.items %}
  {{ }} - {{ item.price }} <br/>
{% endfor %}

This will loop through your data and output the items that were passed in with the purchase event.