Using Liquid to Personalize Your Campaigns

Very often we see companies create a number of very similar campaigns, which only vary slightly. This is not the best practice — you’d have to set up (or change) the same messages multiple times.

There’s a better way! Sometimes you’ll need your emails to be a bit smarter than plain-text. That’s when Liquid comes to help: you can use conditions, insert variables, and do many other great things to personalize your campaigns.

What is Liquid?

Liquid is an open-source template language created by Shopify. Here’s the official full-text manual for your reference. In this guide, you’ll find a few key elements and ideas for customizing your campaigns.

How can I make sure that my Liquid tags work properly?

Our message preview feature allows you to test messages using data from any individual user. You can select one one of the names on the right, or find a particular person using the search field. To open the preview window, click "Preview" in the top right corner of the screen.

Property tags provided by Userlist

In Userlist, you can use Liquid tags in message subject, message body, and footer settings. Tags are formatted like this: {{ tag name }}. Below is a list of tags to use if you want to insert specific properties.

User Properties

Tag Description
{{ }} User’s internal ID (probably won’t be necessary in your messages)
{{ user.identifier }} User’s identifier as provided via the Push API
{{ }} User’s email address
{{ user.custom_property }} User’s custom property of the given name. Common examples (these will only work if you specifically send them to Userlist):
{{ user.first_name }},
{{ user.last_name }}.

Sidenote: if there is a system property of the same name (i.e. a naming conflict), then your custom property can be specifically accessed by
{{ }}.

Your Account Properties

Tag Description
{{ }} Internal account ID (probably won’t be necessary in your messages)
{{ }} Your company (product) name as defined in Company Settings
{{ }} Your company website URL as defined in Company Settings
{{ account.postal_address }} Postal address as defined in Company Settings
{{ account.inline_postal_address }} Postal address converted into one-line format (new lines become commas)
{{ account.default_sender_name }} Default sender name as defined in Email Settings (it’s usually better to use
{{ message.sender_name }} though)
{{ account.default_sender_address }} Default sender email address as defined in Email Settings (it’s usually better to use
{{ message.sender_address }} though)
{{ account.default_footer }} Default footer as defined in Email Settings (it’s usually better to use
{{ message.footer }} though)

Message Properties

Tag Description
{{ message.subject }} Message subject
{{ message.footer }} Message footer (always the account default right now). It’s automatically included in the template, so most likely you won’t need it inside the message body.
{{ message.unsubscribe_url }} Unsubscribe URL (just the URL, not the entire link)

Using conditions

You can hide, show, or customize parts of your messages using conditions (formally called control flow tags in Liquid). Such tags are formatted like this: {% sample tag %}


Shows a part of your message only if a certain condition is true. In the following example, we highlight marketing features to marketers only:

{% if user.occupation == 'marketer' %}
  You can use to instantly transform photos into marketing materials.
{% endif %}


The opposite of if — shows a part of your message only if a certain condition is not met. In the following example, we describe the features to everyone but designers:

{% unless user.occupation == 'designer' %}
  Our features can help you process graphics without an in-house designer.
{% endunless %}

The same result could be achieved using if and != (is not equal to):

{% if user.occupation != 'designer' %}
  Our features can help you process graphics without an in-house designer.
{% endif %}


Adds more conditions within an if block. In the following example, we include a specific sentence for marketers, and show a generic sentence otherwise:

{% if user.occupation == 'marketer' %}
  You can use to instantly transform photos into marketing materials.
{% else %} is a versatile tool for all kinds of agency roles.
{% endif %}


Allows you to customize a part of copy based on a variety of values. In the following example, we customize the introduction based on the user’s occupation (marketer, designer, or photographer), and show a generic introduction to everybody else:

{% case user.occupation %}
  {% when 'marketer' %}
     Dear marketers,
  {% when 'designer' %}
     Dear designers,
  {% when 'photographer' %}
     Dear photographers,
  {% else %}
     Dear users,
{% endcase %}

Logic operators

In the above examples, we’ve been using == (is equal to) to compare values. Below you’ll find other logic operators to use:

Operator Description
== Is equal to
!= Is not equal to
< Is less than
<= Is less than or equal to
> Is greater than
>= Is greater than or equal to
and Checks that both condition A and condition B exist
or Checks that either condition A or condition B exist
contains Checks for a substring within a string or an array

Available filters

In addition to the standard filters of Liquid, we offer a couple of filters that are unique to Userlist.

Description Example Output
Formats a number with delimiters and a separator to be more human readable  {{ user.total_photos | format_number }} 325,234
Formats (and rounds) a number as currency {{ user.ltv | format_currency }} $1,230.55

Popular customization formulas

Use a default placeholder

Use a placeholder if the property hasn’t been specified. The following example will say friend if there’s no first name available:

{{ user.first_name | default: "friend" }}

Capitalize property values

The following example capitalizes the first_name property with the capitalize filter:

{{ user.first_name | capitalize }}

Combined with the previous placeholder formula, it would look like this:

{{ user.first_name | capitalize | default: "friend" }}

The default "friend" value won’t be capitalized because capitalize only applies to everything on the left (it’s called “pipeline” syntax). Similar to capitalize, you can also use upcase and downcase to convert the value to uppercase or lowercase.

Show the first name

If you only have full_name of your users available, you can extract their first name (the first word) with the following formula:

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

Format date & time

To make date & time properties readable, you should customize their format when inserting them into your messages. Here are some common examples:

Example Output
Your trial expires on {{ user.trial_expiration | date: "%B %-d, %Y" }} Your trial expires on January 7, 2019
Congratulations, you’ve been with us since {{ user.signed_up | date: "%Y" }} Congratulations, you’ve been with us since 2015
Today is {{ now | date: "%A, %b %d, %Y at %I:%M %P" }} Today is Tuesday, Oct 06, 2018 at 06:15 pm

You can find the full list of date & time placeholders in this documentation.

Show how many days are left in a trial

Here’s an example showing how many days are left in user’s trial:

Thanks for being with us! You have {% assign current_date = 'now' | date: '%s' %}{% assign future_date = user.trial_expiration %}{{ future_date | minus: current_date | divided_by: 86400 }} days left in your trial.

We’re calculating the difference between two dates and dividing it by 86400 (number of seconds in a day). The result will be rounded down.

Humanize numbers

You can user the following formula to display integers as words (e.g. “two” or “fifty five”):

Congrats, you have taken {{ user.recent_photos | humanize }} photos today!

Still need help? Contact Us Contact Us