Christopher Orr

Useful examples of Snippets on Customer.io

Here are a few examples of how I use the Snippets feature on Customer.io Journeys. Snippets are handy dynamic shortcuts you can use in your messages: whether in an email subject or body, in a push notification, a Slack message, or anywhere else.

Customer.io Snippets are powerful because they can use Liquid templating logic, they can access the profile attributes for each of your customers, and because you can quickly include them anywhere in your messages just by writing {{snippets.name}}.

1️⃣ Show the correct emoji for the customer’s location

Sometimes, a tiny touch — something as small as the right emoji — can make a product feel more intentional and human. For Planet Wild, where everything we do is very much connected to our planet, we often use the Earth emoji in email subject lines.

As I was setting up one such email on Customer.io, I had a thought… 🤔

When contacting our global community members, we should include the appropriate Earth emoji for where they live! Like I’ve personalised this one for where you are: 🌎

I was already making sure that every profile in Customer.io has the timezone attribute defined, so that’s what I used to create this earth snippet:

{% capture emoji %}
  {% if customer.timezone contains 'America/' %}
  🌎
  {% elsif customer.timezone contains 'Asia/'
        or customer.timezone contains 'Australia/'
        or customer.timezone contains 'Indian/'
        or customer.timezone contains 'Pacific/' %}
  🌏
  {% else %}
  🌍
  {% endif %}
{% endcapture %}
{{ emoji | strip }}

I was then able to write an email subject line like this, which shows the correct emoji for each recipient when sent:

Welcome to Planet Wild! {{snippets.earth}}

How this works

Customer.io supports time zone formats that include the standardised “tzdb” IDs, which look like Europe/Berlin, Pacific/Auckland, or America/Sao_Paulo.

The full set of time zone database identifiers arranges the globe into ten regions:

$ curl -s 'https://raw.githubusercontent.com/vvo/tzdb/refs/tags/v6.149.0/raw-time-zones.json' \
    | jq -r '.[].name' | cut -d/ -f1 | sort | uniq
Africa
America
Antarctica
Arctic
Asia
Atlantic
Australia
Europe
Indian
Pacific

My earth snippet tries to select the best emoji based on the timezone’s region, falling back to the globe emoji for Europe in case of other regions, or if the Customer.io profile is missing a timezone attribute for some reason.

I’m using capture to place the value into a variable caled emoji, and then outputting it with strip at the end, so that the emoji is shown without whitespace on either side. Without this, all the spaces and newlines within this snippet would be part of the output.

2️⃣ Include details of the customer’s payment method

Being able to remind a customer of which payment method they used — e.g. when a monthly subscription payment fails — is another useful personalisation we can make.

For example, a message like this in an email:

We were unable to charge your {{snippets.payment_method}}…

Will result in a personalised message such as:

We were unable to charge your card ending in 4242…
We were unable to charge your PayPal account…
We were unable to charge your bank account ending in 0898…

Here’s my payment_method snippet used to implement this:

{% capture details %}
  {% case customer.payment_method.type %}
    {% when "card" %}card ending in {{customer.payment_method.last_4}}
    {% when "paypal" %}PayPal account
    {% when "sepa_debit" %}bank account ending in {{customer.payment_method.last_4}}
    {% else %}payment method
  {% endcase %}
{% endcapture %}
{{ details | strip }}

Note that in case we don’t have details for a customer, or they use a payment method type that’s not recognised by the snippet, the message will still make grammatical sense — it just falls back to mentioning a generic “payment method”.

How this works

This requires that Customer.io profiles of paying customers have up-to-date information about the payment method they use.

The snippet above takes advantage of the fact that profile attributes can contain JSON, and that nested data can be easily accessed, such as customer.payment_method.type.

So each of our subscription customers has an attribute like this, which we update whenever their payment details are updated:

"payment_method": {
  "type": "sepa_debit",
  "last_4": "0898"
}

The payment method type is the value that we check in the snippet (e.g. card, paypal) and use to customise the message. We use Stripe for payments, so the value of this type field is determined by their API. For methods that have an associated account number, we store the last four digits, which are safe to store outside of Stripe.

The fallback {% else %} statement is used if the customer’s payment method type is unexpected. For example, perhaps we enable a new type of payment method on Stripe, but forget to update this snippet.

As above, I’m using capture to place the message into a variable, and outputting it without any surrounding whitespace, so it can be used directly within a sentence.

3️⃣ Remind the customer why they’re signed up

This is a simple idea, but it can serve as a useful reminder to a customer when they start searching for the “Unsubscribe” link in your email.

Customers don’t spend as much time thinking about your service as you do, and if it’s been a while since you last contacted them, they may have even forgotten signing up for your service, or newsletter, or whatever it may be.

So keeping track of where a customer signed up or opted-in can come in very handy. With this snippet, you’ll be able to include a little notification like this:

We sent this message to [email] because you…
 …created an account on example.com in Nov 2024.
 …signed up from the Example mobile app in Nov 2024.
 …subscribed to our Cool Examples newsletter in Nov 2024.

Which would just require including something like this when composing an email:

We sent this message to {{customer.email | downcase}}
 because you {{snippets.signup_reason}}.

If you no longer wish to receive updates about XYZ you can <unsubscribe>.

Here’s the signup_reason snippet:

{% capture signup_date %}
  {{ customer.created_at | date: '%b %Y' }}
{% endcapture %}
{% capture source %}
  {% case customer.signup_source %}
    {% when "app" %}
      signed up from the Example mobile app in {{signup_date | strip}}
    {% when "newsletter" %}
      subscribed to our Cool Examples newsletter in {{signup_date | strip}}
    {% else %}
      created an account on example.com in {{signup_date | strip}}
  {% endcase %}
{% endcapture %}
{{ source | strip }}

How this works

This requires that you do some work to keep track of how you acquired each customer.

In this case, I use a signup_source attribute, which is set as appropriate by our backend whenever a new customer account is created. In addition, the current timestamp is stored in the created_at field (which Customer.io recommends you do).

This allows us to include {{ customer.created_at | date: '%b %Y' }}, which uses Liquid’s fairly powerful date formatting options to show something brief like Nov 2024.

Again, there’s a fallback option, in case we’re missing information. As with the snippets above, we make good use of capture and strip to generate text that can be seamlessly incorporated within a sentence.


I hope these examples can provide some inspiration for your campaigns. Let me know what you come up with!