Liquid syntax list
UpdatedThis page contains a list of the liquid tags, keys, and filters available to you in Customer.io. If you’re new to liquid, you can learn more in our guide about personalizing messages.
You're looking at the latest Liquid documentation
If your account was created on or after Nov 28, 2023, you are using our latest liquid version for all messages. If your account was created before this date, go to How to upgrade your liquid version for more info.
The two versions are largely similar, but you'll find a list of differences on our Liquid Upgrade page.
Looking for something specific?
- Customer.io Keys- These are values generated by, or stored within, Customer.io. Reference these values to import information. Many of the - .idvalues are useful as UTM parameters in links so you can log where your traffic is coming from or attribute customer actions to messages.
- Logical Operators- Logical operators determine the basic rules for evaluating true or false statements. You can also use - andand- oroperators to combine logic statements to evaluate multiple conditions.
- Timestamps and Dates- Use these tags to get and manipulate dates and times. 
- Array Filters- Liquid used to filter and manipulate arrays (lists of values). If your event or another incoming value is an array, you may iterate over the array with a - forloop or grab items at a particular index of the array, to display information for your audience.
- Number and Currency Filters- These are tags and filters that manipulate incoming number, integer, and timestamp values. - Some tags, like the - currencyand- format_number, take an optional localization parameter, formatting the output for a specific locale. These tags use the format- {{ 10 | currency: "en-us" }}, which would output- $10.00.
- Math Filters- Filters that perform math operations on incoming number or integer values. With the legacy liquid version, if you encounter an error with negatives while using math filters, wrap the negative numbers in quotes. 
- String Filters- The following filters manipulate strings in templates. You might use these to truncate or set the case of strings you reference from other places, to humanize your messages for recipients. 
- Miscellaneous- These are tags that you can use to escape liquid rendering or escape rendering all together. 
- Customer.io Keys- These are values generated by, or stored within, Customer.io. Reference these values to import information. Many of the - .idvalues are useful as UTM parameters in links so you can log where your traffic is coming from or attribute customer actions to messages.
- campaign.id- “Your campaign’s numerical ID. This can be found in your campaign URL. For example, the campaign ID here is 2000: - https://fly.customer.io/env/12345/v2/campaigns/2000/overview.- For newsletters, your - campaign.idis the value after- newslettersin your URL. For example, the newsletter’s- campaign.idhere is- 1- https://fly.customer.io/env/109950/composer/newsletters/1/templates/21.”- Syntax- {{campaign.id}}
- campaign.name- The name that you assigned your campaign or newsletter. For example: “Q2 Anvil Onboarding Campaign [Coyotes]”. - Syntax- {{campaign.name}}
- campaign.subscription_topic_ids- To use this, you must enable our subscription center. This returns the topic assigned in subscription preferences settings for Campaigns, API Triggered Broadcasts and Newsletters. - Syntax- {{campaign.subscription_topic_ids}}
- campaign.type- This returns the type of trigger for your campaign: - behavioral(legacy segment-triggered),- seg_attr(attribute or segment-triggered),- transactional(event-triggered),- form,- date,- object, or- relationship. For messages sent through our Transactional API, this returns- transactional_message. It also returns- triggered_broadcastfor an API-triggered broadcast or- newsletteraccordingly.- Syntax- {{campaign.type}}
- cio_link- Use this tag to track links in non-email messages (SMS, push, or slacks) as well as - mailtolinks. If you use our SDKs, you do not need to use this tag to track links in in-app messages or push notifications. To track links in emails, go to- cio_link_idbelow.- The filters - trackand- url_paramsare optional. If you exclude these filters, url parameters will be present and tracking will be on. To turn either off, set them to false. For more info on this tag, go to Link tracking.- Do not use this tag to track deep links. - Example- {% cio_link url:https://example.com %} {% cio_link url:https://example.com track:true url_params:true %} {% cio_link url:https://example.com track:true url_params:false %} {% cio_link url:https://example.com track:false url_params:true %} {% cio_link url:https://example.com track:false url_params:false %}- Output- https://e.customeriomail.com/e/c/{string} https://e.customeriomail.com/e/c/{string} https://e.customeriomail.com/e/c/{string} https://example.com?utm_campaign={string}&utm_content={string}&utm_medium={string}&utm_source=customer.io https://example.com
- cio_link_id- Use this to track deep links in emails. Visit Track universal and app links in email for instructions. - For links in non-email messages, go to - cio_linkabove.- Example- <a href="https://yourwebsite.com/confirm?link_id={% cio_link_id %}" class="untracked">Text</a>
- content- Use in layouts to indicate where code added via the email editor will be included. You might use this in a template for a transactional message or API-triggered broadcast where you will provide content from the API directly. - Example- {{content}}
- customer attributes- You reference customer attributes—data associated directly with a person in Customer.io—in the - customerscope. You may want to use customer attributes with an- ifconditional so you have text to fallback to if a customer doesn’t have the attribute in question. You can use- defaultrather than checking for empty strings using- == blankor- != blank.- Syntax- {{customer.<attribute_name>}}- Example- Hi {{ customer.first_name | default: "there" }} {% if customer.first_name != blank %} Hello {{ customer.first_name }}! {% else %} Hello there! {% endif %}
- delivery_id- A URL-compatible base64 string that identifies an instance of a message created for a person. This is set to unsent in test send and composer previews, and generated when the message is drafted or sent. - Syntax- {{delivery_id}}
- event properties- If you trigger a campaign using an event, you can reference properties from the event that triggers your campaign in the - eventscope. You may want to use event properties with an- ifconditional, so that you have text to fallback to if an event doesn’t have the property in question or your property doesn’t contain the value you expect. You can use the- defaultfilter rather than checking for empty strings using- == blankor- != blanktoo.- Syntax- {{event.<property>}}- Example- {% if event.type == "purchase" %} Thanks for your purchase! {% else %} Thanks for using our service! {%endif%}
- event_id- The id of the event being previewed for the selected sample profile. It throws an error if the event has not been sent recently (within the last ~30 days). - Syntax- {{event_id}}
- event_name- The name of the event that triggers a campaign. If you send an event with different casings - for instance, MyEvent and myevent - Customer.io will output the event name that corresponds with the profile. This throws an error if the event has not been sent recently (within the last ~30 days). - Syntax- {{event_name}}
- layout.id- The numerical ID associated with the email layout you’ve used. - Syntax- {{layout.id}}
- layout.name- The name assigned to the email layout you’re using. - Syntax- {{layout.name}}
- manage_subscription_preferences_url- Renders a unique unsubscribe link for a customer and their email-address. This link takes a user to your subscription center where they can manage all of their preferences. - Syntax- {% manage_subscription_preferences_url %}
- message.id- The numerical ID for a message action in the workflow. For example, an SMS action might have a - {{message.id}}of 200. Note that this identifies the action in your workflow, not the individual delivery instances. Every SMS delivery generated from the action would have a different- {{delivery_id}}.- For newsletters, the - message.idis the value after templates in your URL. For example, the- message.idhere is- 21- https://fly.customer.io/env/109950/composer/newsletters/1/templates/21.- Syntax- {{message.id}}
- message.journey_id- The ID for the path a person went through in a Campaign or API Triggered Broadcast workflow. You can use this value to trace message metrics back to a person’s path through a journey using the - journey.idvalue sent in our Reporting Webhooks.- Syntax- {{message.journey_id}}
- message.name- The name you give your message in the workflow, like “Welcome to ACME!” - Syntax- {{message.name}}
- message.preheader- For email messages only, if your message has a preheader value set, this tag echos it. - Syntax- {{message.preheader}}
- message.subject- If your message has a subject, or the message subject is different from the message name, this tag echos it. - Syntax- {{message.subject}}
- message.subscription_topic_ids- To use this, you must enable our subscription center. This returns the topic ID of the subscription preference assigned to Campaigns, API-triggered Broadcasts and Newsletters. If there is a message-level override of the topic (Campaigns and API-triggered Broadcasts only), it will return the message-level topic ID. - Syntax- {{message.subscription_topic_ids}}
- message.subscription_topic.name- To use this, you must enable our subscription center. Renders the name of the subscription topic assigned to a broadcast or campaign. If the topic is overriden for a message, this will render the message-level topic name. - Syntax- {{message.subscription_topic.name}} {{message.subscription_topic.name | default: "Unsubscribe"}}
- message.type- This refers to the type of a particular workflow action. Possible values are: - email_action,- delay_seconds_action,- delay_time_window_action,- split_randomized_action,- webhook_action,- twilio_action,- slack_action,- attribute_update_action,- filter_match_delay_action,- grace_period_action,- push_action,- conditional_wait_action,- conditional_branch_action,- multi_split_branch_action,- random_cohort_branch_action,- exit_action,- static_seg_update_action,- collection_query_action,- create_event_action,- multi_lang_branch_action,- batch_update_action,- in_app_action.- Syntax- {{message.type}}
- snippets- Create snippets to reuse content across your messages. For instance, you could make a footer with a snippet. - Example- {{snippets.footer}}
- subscription_topic_name- To use this, you must enable our subscription center. Renders the name of the subscription topic assigned to a broadcast or campaign. If the topic is overriden for a message, this will render the message-level topic name. Add a language parameter to translate the name, like - lang='pt'. If the language doesn’t match a translation in your subscription center, customers will see the default language.- Syntax- {% subscription_topic_name %} {% subscription_topic_name lang='pt' %}
- trigger properties- You can reference properties from the - dataobject when you trigger a transactional message or API-trigger a broadcast using the- triggerscope. This provides a convenient way to pass event data into transactional and broadcast templates. You may want to use trigger properties with an- ifconditional, so that you have text to fallback to if your trigger data is incomplete or contains values you don’t expect. You can use the- defaultfilter rather than checking for empty strings using- == blankor- != blank.- Syntax- {{trigger.<data.property>}}- Example- {% if trigger.first_name %} Hi {{trigger.first_name | capitalize}} {% else %} Hi Buddy {%endif%}
- unsubscribe- Renders the word unsubscribe and links to the customer’s unique unsubscribe URL. - Syntax- {% unsubscribe %}
- unsubscribe_url- Renders a unique unsubscribe link for a customer and their email-address. - Syntax- {% unsubscribe_url %}
- view_in_browser_url- Our default link that generates a web version of your email, personalized for each recipient. In general, these URLs look something like: - http://e.customeriomail.com/deliveries/....- Syntax- {% view_in_browser_url %}
- assign- Assign a value to a variable. - Syntax- {% assign var_name = 'value' %}- Input- {% assign favorite_food = 'apples' %}- Output- {{ favorite_food }}
- capture- Captures contents and assigns them to a variable. - Input- {% capture about_me %}I am 28 and my favorite food is pasta.{% endcapture %}- Output- {{ about_me }}
- cycle- In a ‘for’ loop, this tag loops through and outputs strings in the order they were passed. - Input- <ul>{% assign characters = "coyote,bugs,tweety" | split: "," %} {% for character in characters %} <li class="{% cycle 'odd', 'even' %}">{{ character }}</li> {% endfor %} </ul>- Output- <ul> <li class='odd'>coyote</li> <li class='even'>bugs</li> <li class='odd'>tweety</li> </ul>
- for loop- Repeatedly executes a block of code, most commonly to perform an operation for each item in an array. You might use a for loop in a message to provide a receipt of purchases (assuming an array of items in a purchase). Find more information about for loops and iteration here. For instance, you can use a break tag - {% break %} - to exit a loop. - Syntax- {% for item in array %} {{ item }} {% endfor %} {% comment %} You can use a break tag so the loop stops iterating. {% endcomment %} {% for i in (1..5) %} {% if i == 4 %} {% break %} {% else %} {{ i }} {% endif %} {% endfor %}- Example- {% comment %} You can output each item of the array. {% endcomment %} {% for member in members_of_band %} {{member}} {% endfor %} {% comment %} If the items are objects, you can output properties from each object. {% endcomment %} {% for product in event.products %} - {{ product.title }} x {{ product.price }} {% endfor %}
- case- Creates a set of conditions depending on a variable’s specific value—like a set of if, if-else, else conditions. - For example, you might use this to display different text depending on if a customer lives in a specific country. - Syntax- {% case condition %} {% when "value1" %} text when condition is value1. {% when "value2" or "value3" %} text when condition is value2 or value3 {% else %} text when condition does not match other conditions {% endcase %}
- if- Executes a block of code if a condition is met. We execute the first true condition. Use - elsifto add multiple ‘if’ conditions and- elsefor the block of code you want to execute if all conditions are false. Use the- defaultfilter to specify a fallback for when a variable does not exist instead of an if statement. Find more information about conditional liquid here.- Example- {% if customer.lastEventType == "sports" %} You last attended a sports event, so we thought you might like to try out our leagues! Fill out our interest form below. {% elsif customer.lastEventType == "theater" %} You attended a theater event, so we thought you might like to try out our after show parties! Fill out our interest form below. {% elsif customer.lastEventType %} {% comment %} If the attribute exists and does not equal sports or theater, then this will render.{% endcomment %} You last attended {{customer.lastEventType}}; we'd love to hear what other offerings you'd like from us in the form below. {% else %} {% comment %} If the attribute does not exist, this will render. {% endcomment %} Let us know your interests in the form below so we can better serve you! {% endif %}
- unless- Like an if conditional, but reversed: this tag executes a block of code if your condition is not met. - Example- {% unless product.name == "cool beans" %} The beans are not cool. {% endunless %}
- Logical Operators- Logical operators determine the basic rules for evaluating true or false statements. You can also use - andand- oroperators to combine logic statements to evaluate multiple conditions.
- and- Evaluate a statement as true when both conditions are true. - Syntax- {% if condition1 and condition2 %} // do something if both condition1 and condition 2 are true {% endif %}- Example- {% if customer.name == "bugs bunny" and event.episode_start == true %} What's up doc? {% else %} That's all folks! {% endif %}
- does not equal (!=)- Use - !=to check that two values are not equal to each other.- Example- {% if customer.name != "daffy duck" %} Duck season! {% else %} Wabbit season! {%endif%}
- equals (==)- Use - ==to check if two values are equal to each other.- Example- {% if customer.name == "daffy duck" %} Wabbit season! {% else %} Duck season! {% endif %}
- greater than and greater than or equal to (>, >=)- Use - >to match when one value is greater than another. Use- >=to match when one value is greater than or equal to another.- Syntax- {% if val1 > val2 %} {% comment %}do something if val1 is greater than val2{% endcomment %} {% endif %}- Example- {% if customer.acct_age_years > 1 %} Thanks for being with us these past years {% else %} Thanks for spending the last year with us! {% endif %}
- less than and less than or equal to (<, <=)- Use - <to match when one value is less than another. Use- <=to match when one value is less than or equal to another.- Syntax- {% if val1 < val2 %} {% comment %}do something if val1 is less than val2{% endcomment %} {% endif %}- Example- {% if customer.purchases < 5 %} Thanks for your support {% else %} Thanks for spending the last year with us! {% endif %}
- or- Evaluate a statement as true when either of two conditions are true. - Syntax- {% if condition1 or condition2 %} {% comment %}do something if either condition1 and condition 2 are true{% endcomment %} {% endif %}- Example- {% if customer.name == "bugs bunny" or customer.group == "looney toons" %} That's all folks! {% else %} See you later! {% endif %}
- Timestamps and Dates- Use these tags to get and manipulate dates and times. 
- add_day- Adds a day, or multiple days, to a given timestamp. - Syntax- {{ <unix_timestamp> | add_day: <int_days> }}- Example- {{ 1477430251 | add_day: 7 }}
- add_month- Adds a month, or multiple months, to a given timestamp. - Syntax- {{ <unix_timestamp> | add_month: <int_months> }}- Example- {{ 1477430251 | add_month: 7 }}
- add_year- Adds a year, or multiple years, to a given timestamp. - Syntax- {{ <unix_timestamp> | add_year: <int_years> }}- Example- {{ 1477430251 | add_year: 4 }}
- countdown- Creates a countdown timer in your message, helping you alert your audience to how soon an event they’re interested in is set to happen. Countdown timers take several parameters. At the minimum, a countdown must include the font size, the foreground (font) color, the background color, and the time you want to count down to. You can only set this to count down from a static timestamp; you cannot set the time to count down based on a customer’s attribute, for instance. - The countdown timer cannot contain more than 60 frames. This limits the size of the animated GIF in your messages. So, if the resolution is set to seconds, the counter will stop after 60 seconds from when the person opens their message. The countdown image reloads when a person opens the message again, so the counter will always be relevant to the user’s current time, but it cannot count indefinitely. - Parameter - required - format - default - description - point - ✓ - integer - The font size for the timer - time - ✓ - ISO 8601 timestamp - The date and time you want to countdown to in the format - YYYY-MM-DD hh:mm:ss (GMT). Remember to close the time in quotes, as the value includes a space. This field does not accept liquid variables.- fg - ✓ - hex color - The foreground (font) hexidecimal color - bg - ✓ - hex color - The background hexidecimal color - apng - boolean - false - Determines whether to show your countdown as a gif (default) or animated PNG. Note that some browsers/email clients don’t support apng images. - font - string - inter, roboto - The font family for your timer - weight - string - normal - The font weight, takes normal CSS - font-weightvalues.- locale - language code - en - The language you want to display: - en(English),- ru(Russian),- jp(Japanese),- zh(Chinese),- pt(Portugese),- es(Spanish), and- fr(French)- looping - boolean - false - Determines whether the countdown timer should restart after it finishes - resolution - one of S, M, H, D - S - Determines how often the timer counts down—by the second, minute, hour, or day. - frames - integer - 1 - Number of seconds you want to show, based on the resolution, where seconds: 60, minutes: 2, hours: 1, days: 1 - Example- {% countdown point:64 font:roboto weight:light fg:000000 bg:f2f6f9 time:"2022-07-04 12:00:00 (GMT)" locale:en looping:true resolution:S frames:2 %}  
- date- Format a date. Use the LiquidJS reference for more information about date filters including overriding the time zone. For a full list of regions, see our Supported time zone formats. You can also offset the time zone in minutes (360 = -6:00 hrs and -360 = +6:00 hrs). - Input- {{ 1483272000 | date: '%H:%M, %a, %b %d, %Y' }} {{ 1483272000 | date: '%a., %-m/%d at %I:%M %P %Z' }} {{ "1990-12-31T23:00:00Z" | date: "%Y-%m-%dT%H:%M:%S", "Asia/Colombo" }} {{ "1990-12-31T23:00:00Z" | date: "%Y-%m-%dT%H:%M:%S", 360 }}- Output- 12:00, Sun, Jan 01, 2017 Sun., 1/01 at 12:00 pm UTC 1991-01-01T04:30:00 1990-12-31T17:00:00
- date_to_long_string- Converts a date-time to include the full name of the month. You can convert this to ordinal time by adding ‘ordinal’, and you can follow that with ‘US’ if you’d like to lead with the month. By default, this displays the date in DD, M full name, YYYY. - Input- {{ site.time | date_to_long_string }} {{ site.time | date_to_long_string: "ordinal" }} {{ site.time | date_to_long_string: "ordinal", "US" }}- Output- 07 November 2008 7th November 2008 November 7th, 2008
- date_to_rfc822- Converts a date-time into the RFC-822 format used for RSS feeds. - Input- {{ site.time | date_to_rfc822 }}- Output- Mon, 07 Nov 2008 13:07:54 -0800
- date_to_string- Converts a date-time to ordinal time. Add ‘US’ to lead with the month. By default, this displays the date in DD, M abbreviated, YYYY. - Input- {{ site.time | date_to_string }} {{ site.time | date_to_string: "ordinal" }} {{ site.time | date_to_string: "ordinal", "US" }}- Output- 07 Nov 2008 07th Nov 2008 Nov 7th, 2008
- date_to_xmlschema- Converts a date-time into ISO 8601, a format expected by XML schema. - Input- {{ site.time | date_to_xmlschema }}- Output- 2008-11-07T13:07:54-08:00
- event_timestamp- The UNIX timestamp when a particular event was performed. This time is different from the - nowtag! This throws an error if the event has not been sent recently (within the last ~30 days).- Syntax- {{event_timestamp}}
- now- The current time in UTC. You must format time with - date.- To modify date or time with - addor- subtractfilters you must convert- nowinto a unix timestamp first using- date: '%s'. If you use our built in- add_day,- add_month, or- add_yearfilters, you must convert the timestamp to an integer first. You can do this by using the- plusfilter to add- 0as shown in the second example below.- Example- {{ 'now' | date: '%I:%M %p %B %d, %Y' }} {{ 'now' | date: '%s' | plus: 0 | add_day: 1 | date: '%I:%M %p %B %d, %Y'}}- Output- 08:28 AM May 11, 2021 08:28 AM May 12, 2021
- subtract_day- Subtracts a day, or multiple days, to a given timestamp. - Syntax- {{ <unix_timestamp> | subtract_day: <int_days> }}- Example- {{ 1477430251 | subtract_day: 7 }}
- subtract_month- Subtracts a month, or multiple months, to a given timestamp. - Syntax- {{ <unix_timestamp> | subtract_month: <int_months> }}- Example- {{ 1477430251 | subtract_month: 2 }}
- subtract_year- Subtracts a year, or multiple years, to a given timestamp. - Syntax- {{ <unix_timestamp> | subtract_year: <int_years> }}- Example- {{ 1477430251 | subtract_year: 4 }}
- Array Filters- Liquid used to filter and manipulate arrays (lists of values). If your event or another incoming value is an array, you may iterate over the array with a - forloop or grab items at a particular index of the array, to display information for your audience.
- compact- Removes - nil(empty) values from an array.- Input- {{ "mick, keith, nil, Charlie" | compact }}- Output- mick, keith, Charlie
- concat- Concatenates arrays, joining them end to end. Accepts a single object or an array of objects. The resulting array contains all of the elements of both original arrays. - concatdoes not remove duplicate entries unless you also use the- uniqfilter.- Input- {% assign stones = "mick, keith, ronnie, charlie" | split: ", " %} {% assign beatles = "john, paul, george, ringo" | split: ", " %} {% assign rolling_beatles = stones | concat: beatles %} {{ rolling_beatles | join: ", " }}- Output- mick, keith, ronnie, charlie, john, paul, george, ringo
- find- Returns the first object in an array for which the queried attribute has the given value or returns nil if no item in the array satisfies the given criteria. - Input- {{ customer.purchases | find: "type", "kitchen" | json }}- Output- {"date":"1726589206","title":"utensils","type":"kitchen"}
- find_exp- Returns the first object in an array for which the given expression evaluates to true or returns nil if no item in the array satisfies the evaluated expression. - Input- {{ members | find_exp: "item", "item.graduation_year == 2014" | json }}- Output- {"graduation_year":2014,"name":"John"}
- first- Returns the first element of the array. - Input- acme.characters = ["Wile E Coyote", "Road Runner"] {{ acme.characters | first }}- Output- Wile E Coyote
- group_by- Groups an array’s items by a given property. - Input- {% assign groups = customer.purchases | group_by: "type" %} {% for group in groups %} {{group.name | capitalize}} {% for item in group.items %} - {{ item.title }} {% endfor %} {% endfor %}- Output- Bathroom - shower curtain - body soap Kitchen - forks - spoons - knives
- group_by_exp- Groups an array’s items using a Liquid expression. - Input- {% assign groups = customer.purchases | group_by_exp: "item", "item.type contains 'kitchen'" %} {% for group in groups %} {% if group.name == true %} You bought some kitchen supplies from us in the past year: {% for item in group.items %} - {{item.title}} {% endfor %} {% endif %} {% endfor %}- Output- You bought some kitchen supplies from us in the past year: - forks - spoons - knives
- join- Joins the elements of an array with the character passed as the parameter. - Input- acme.characters = ["Wile E Coyote", "Road Runner"] {{ acme.characters | join: ', ' }}- Output- Wile E Coyote, Road Runner
- json_array_uniq- Evaluates an array of JSON objects and outputs an array containing all the unique objects based only on the value of the passed-in key name. Use the filter - to_jsonif a string is the desired output.- Input- {{ customer.arrayOfColorObjects | concat: customer.arrayOfColorObjectsWithDuplicationsAndNew | json_array_uniq: 'name' | to_json }}- Output- [{"color":"brown","name":"coyote"},{"color":"black","name":"bugs"},{"color":"yellow","name":"tweety"},{"color":"black","name":"daffy"}]
- last- Returns the last element of the array. - Input- acme.characters = ["Wile E Coyote", "Road Runner"] {{ acme.characters | last }}- Output- Road Runner
- limit- Return a set number of values from an array or string. - Input- {% assign beatles = "john, paul, george, ringo" | split: ", " %} {{ beatles | limit: 2 | join: ", " }}- Output- john, paul
- map- Creates an array of values by extracting the values of a property in an object. You can output your new characters in a ‘for’ loop. - Input- Array of objects: [{"name":"coyote"},{"name":"bugs"},{"name":"tweety"}]" {% assign names = customer.characters | map: 'name' %}- Output- coyote, bugs, tweety
- pop- Removes the last element from the array. - Input- {% assign fruits = "apples, oranges, peaches" | split: ", " %} {% assign everything = fruits | pop %} {% for item in everything %} - {{ item }} {% endfor %}- Output- - apples - oranges
- push- Adds an element to an array. - Input- {% assign fruits = "apples, oranges" | split: ", " %} {% assign everything = fruits | push: "peaches" %} {% for item in everything %} - {{ item }} {% endfor %}- Output- - apples - oranges - peaches
- remove- Remove an element from an array. The array can contain objects of any type. - Input- {% assign pl = customer.products | remove: customer.products[0] %} - {{ customer.products.size }} - {{ pl.size }}- Output- - 2 - 1
- reverse- Reverses the order of the items in an array. - Input- {% assign my_array = "apples, oranges, peaches, plums" | split: ", " %} {{ my_array | reverse | join: ", " }}- Output- plums, peaches, oranges, apples
- shift- Removes the first element from the array. - Input- {% assign fruits = "apples, oranges, peaches" | split: ", " %} {% assign everything = fruits | shift %} {% for item in everything %} - {{ item }} {% endfor %}- Output- - oranges - peaches
- size- Returns the number of characters (the size) of a string (in characters) or the number of elements in an array. - Input- {{ "That's all, folks!" | size }}- Output- 18
- sort- Sorts the elements of an array by an attribute of an element in that array. Usually used with a ‘for’ loop. The order of the sorted array is case-sensitive! This filter will not reorder any list/array that contains null values. See Sorting looped data for an advanced example. - Input- {% assign beatles = "paul, john, ringo, george" | split: ", " %} {{ beatles | sort | join: ", " }}- Output- george, john, paul, ringo
- sort_natural- Sort the items in an array in case-insensitive order. - Input- {{ "mick, keith, Charlie, Ronnie" | sort_natural }}- Output- Charlie, keith, mick, Ronnie
- sum- The - sumfilter aggregates numbers. Every value is cast to a number. Unlike with legacy liquid,- sumdoes not concatenate numbers, strings, or booleans. You can specify an object property to sum, as shown in the third example below.- Input- {% assign nums = '1,2,3' | split: ',' %} {{ nums | sum }} {% assign letters = 'a,b,c' | split: ',' %} {{ letters | sum }} {{ cart.products | sum: 'total_number' }} {% comment %} where `total_number` includes milk,cheese,eggs {% endcomment %} {{ purchase.products | sum }} {% comment %} where `products` includes true,false {% endcomment %}- Output- 6 0 3 1 {% comment %} counts the number of trues, would also aggregate numbers alongside booleans {% endcomment %}
- uniq- Removes duplicate elements in an array. - Input- {% assign my_array = '"lions", "tigers", "bears", "bears", "lions"' %} {{ my_array | uniq | join: ", " }}- Output- lions, tigers, bears
- unshift- Adds an element to the beginning of the array. - Input- {% assign fruits = "oranges, peaches" | split: ", " %} {% assign everything = fruits | unshift: "apples" %} {% for item in everything %} - {{ item }} {% endfor %}- Output- - apples - oranges - peaches
- where- Creates an array including only the objects with a given property value, or any “truthy” value by default. - Input- All Players: {% for player in customer.players %} - {{ player.last_name }} {% endfor %} Baseball Players: {% assign baseball_players = customer.players | where: "sport", "baseball" %} {% for player in baseball_players %} - {{ player.last_name }} {% endfor %} ---------------------------- All products: {% for product in customer.products %} - {{ product.title }} {% endfor %} {% assign available_products = customer.products | where: "available" %} Available products: {% for product in available_products %} - {{ product.title }} {% endfor %}
- where_exp- Selects all the objects in an array where the expression is true. You provide two items separated by a comma: the key you want to match on and the value you want to match. - Input- All products: {% for product in customer.products %} - {{ product.title }} {% endfor %} {% assign kitchen_products = customer.products | where_exp: "item", "item.size > 30 and item.type == 'kitchen'" %} Kitchen products: {% for product in kitchen_products %} - {{ product.title }} {% endfor %}
- where_not- Creates an array of items that do not match a given property value, or any “falsey” value by default. When using - where_not, you provide two items separated by a comma: the key you want to match on and the value you want to match.- Input- All players: {% for player in customer.players %} - {{ player.last_name }} {% endfor %} Not baseball players: {% assign not_baseball_players = customer.players | where_not: "sport", "baseball" %} {% for player in not_baseball_players %} - {{ player.last_name }} {% endfor %}- Output- All players: - Posey - Maradona - Montana - Gretzky - Jordan Not baseball players: - Maradona - Montana - Gretzky - Jordan
- Number and Currency Filters- These are tags and filters that manipulate incoming number, integer, and timestamp values. - Some tags, like the - currencyand- format_number, take an optional localization parameter, formatting the output for a specific locale. These tags use the format- {{ 10 | currency: "en-us" }}, which would output- $10.00.
- A list of locales and currency codes- We support the following localization values: - af, ar, az, be, bg, bn, bs, ca, cs, cy, da, de-AT, de-CH, de-DE, de, dz, el-CY, el, en-AU, en-CA, en-CY, en-GB, en-IE, en-IN, en-NZ, en-TT, en-US, en-ZA, en, eo, es-419, es-AR, es-CL, es-CO, es-CR, es-EC, es-ES, es-MX, es-NI, es-PA, es-PE, es-US, es-VE, es, et, eu, fa, fi, fr-CA, fr-CH, fr-FR, fr, gl, gsw-CH, he, hi-IN, hi, hr, hu, id, is, it-CH, it, ja-JP, ja, ka, kk, km, kn, ko, lb, lo, lt, lv, mg, mk, ml, mn, mr-IN, ms, na, nb, ne, ng, nl, nn, oc, or, pa, pl, pt-BR, pt, rm, ro, ru, sc, sd, sk, sl, sn, sq, sr, st, sv-FI, sv-SE, sv, sw, ta, te, th, tl, tn, tr, tt, ug, uk, ur, uz, vi, wo, za, zh-CN, zh-HK, zh-Hant-MO, zh-MO, zh-TW, ao, cd, ci, cm, eg, gh, ke, ls, ly, ma, mu, mw, mz, sz, tz, zm- We support the following currency codes: - 'AED','AFN','ALL','AMD','ANG','AOA','ARS','AUD','AWG','AZN','BAM','BBD','BDT','BGN','BHD','BIF','BMD', 'BND','BOB','BRL','BSD','BTN','BWP','BYN','BZD','CAD','CDF','CHF','CLP','CNY','COP','CRC','CUC','CUP', 'CVE','CZK','DJF','DKK','DOP','DZD','EGP','ERN','ETB','EUR','FJD','FKP','GBP','GEL','GHS','GIP','GMD', 'GNF','GTQ','GYD','HKD','HNL','HRK','HTG','HUF','IDR','ILS','INR','IQD','IRR','ISK','JMD','JOD','JPY', 'KES','KGS','KHR','KMF','KPW','KRW','KWD','KYD','KZT','LAK','LBP','LKR','LRD','LSL','LYD','MAD','MDL', 'MGA','MKD','MMK','MNT','MOP','MRU','MUR','MVR','MWK','MXN','MYR','MZN','NAD','NGN','NIO','NOK','NPR', 'NZD','OMR','PAB','PEN','PGK','PHP','PKR','PLN','PYG','QAR','RON','RSD','RUB','RWF','SAR','SBD','SCR', 'SDG','SEK','SGD','SHP','SLE','SLL','SOS','SRD','SSP','STN','SVC','SYP','SZL','THB','TJS','TMT','TND', 'TOP','TRY','TTD','TWD','TZS','UAH','UGX','USD','UYU','UZS','VES','VND','VUV','WST','XAF','XCD','XDR', 'XOF','XPF','XSU','YER','ZAR','ZMW','ZWL'
- abs- Returns the absolute value of a number. - Input- {{ 3.14 | abs }}- Output- 3.14
- ceil- Rounds a number up to the nearest integer. - Input- {{ 3.14 | ceil }}- Output- 4
- currency- Converts an integer to currency. This filter accepts two arguments for currency and locale. When no arguments are passed to the filter, the currency code defaults to USD. When only a locale is passed, we base the currency on the closest match to the locale. See above for a list of specific locales and currencies. We only accept a currency code after a locale is specified. - Input- {% comment %} no arguments: {% endcomment %} {{ 1234567.896 | currency }} {% comment %} only locale: {% endcomment %} {{ 1234567.896 | currency: 'en-GB' }} {% comment %} locale and currency code: {% endcomment %} {{ 1234567.896 | currency: 'en', 'EUR' }}- Output- $1,234,567.90 £1,234,567.90 €1,234,567.90
- floor- Rounds a number down to the nearest integer. - Input- {{ 3.14 | floor }}- Output- 3
- format_number- Format a number with a delimiter. This filter also takes an optional localization parameter to format a number for a specific locale. - NOTE: This replaces the former - number_with_delimeterfilter.- Input- {{ 10000 | format_number }} {{ 123456.78 | format_number: "fr" }}- Output- 10,000 123 456,78
- random- Generates a random number between 0 and an integer you specify. - Example- {% random 100 %}
- round- Rounds a number up or down to the nearest integer, or to a decimal place you specify. - Input- {{ 4.32 | round }} {{ 4.32 | round: 1 }}- Output- 4 4.3
- rounded_currency- Rounds a number to the nearest whole integer and formats it to a currency. Accepts both a locale and currency code. We only accept a currency code after a locale is specified. See above for a list of specific locales and currencies. - Input- {% comment %} no arguments: {% endcomment %} {{ 1234567.896 | rounded_currency }} {% comment %} only locale: {% endcomment %} {{ 1234567.896 | rounded_currency: 'en-GB' }} {% comment %} locale and currency code: {% endcomment %} {{ 1234567.896 | rounded_currency: 'en', 'EUR' }}- Output- $1,234,568 £1,234,568 €1,234,568
- Math Filters- Filters that perform math operations on incoming number or integer values. With the legacy liquid version, if you encounter an error with negatives while using math filters, wrap the negative numbers in quotes. 
- at_least- Limits a number to a minimum value. - Input- {{ 41 | at_least: 42 }}- Output- 42
- at_most- Limits a number to a maximum value. - Input- {{ 100 | at_most: 99 }}- Output- 99
- divided_by- Divides a number by another number. - Input- {{ 10 | divided_by: 2.5 }} {{ 10 | divided_by: 4 }} {{ 10 | divided_by: 4.0 }}- Output- 4 2.5 2.5
- minus- Subtracts a number from another number. - Input- {{ 10 | minus: 1 }}- Output- 9
- modulo- Returns the remainder of division. The output will always be a positive number, even when there’s a negative number as input. - Input- {{ 3 | modulo: 2 }}- Output- 1
- plus- Adds a number to another. - Input- {{ 10 | plus: 1 }}- Output- 11
- times- Multiplies a number by another number. - Input- {{ 5 | times: 2 }} {{ 10 | times: 2.5 }}- Output- 10 25
- String Filters- The following filters manipulate strings in templates. You might use these to truncate or set the case of strings you reference from other places, to humanize your messages for recipients. 
- append- Adds a string to the end of another string. - Input- {{ "What's all the hubbub, " | append: "bub?" }}- Output- What's all the hubbub, bub?
- array_to_sentence_string- Converts a list of data into a commma-delineated list. Use in tandem with the - splitfilter.- Input- {{ customer.groceries | split:"," | array_to_sentence_string }} {{ customer.groceries | split:"," | array_to_sentence_string: "or" }}- Output- cherry, kiwi, and passion fruit cherry, kiwi, or passion fruit
- base64- Base64-encodes a string. - Input- {{ 'Hello, world!' | base64 }}- Output- SGVsbG8sIHdvcmxkIQ==
- base64_decode- Decode a base64-encoded string. - Input- {{ "Zm9vLmJhcg==" | base64_decode }}- Output- foo.bar
- base64_encode- Base64-encode a value. - Input- {{ "foo.bar" | base64_encode }}- Output- Zm9vLmJhcg==
- base64_url_safe_decode- Decode a string from URL-safe Base64. - Input- {{ "Zm9vLmJhcg" | base64_url_safe_decode }}- Output- foo
- base64_url_safe_encode- Encode a string into URL-safe Base64. To produce URL-safe Base64, this filter uses - -and- _in place of- +and- /.- Input- {{ "foo" | base64_url_safe_encode }}- Output- Zm9vLmJhcg
- capitalize- Capitalize the first character in a string. - Input- {{ "hello world" | capitalize }}- Output- Hello world
- cgi_escape- CGI escapes a string for use in a URL. - Input- {{ "overview: account" | cgi_escape }}- Output- overview%3A+account
- contains- Finds a substring inside a string, or the presence of a string in an array of strings. This filter only works with strings; you cannot use it to search for an object in an array of object. - Syntax- {% if product.description contains 'lorem ipsum' %} You might also be interested in Fillerama or Office Ipsum. {% endif %}
- downcase- Converts a string to lower case. - Syntax- {{ 'STRING' | downcase }}- Input- {{ "ACME" | downcase }}- Output- acme
- escape- Escaping a string removes special characters. To encode a URL, use - url_encodeinstead.- Input- {{ "win+help@customer.io" | escape }}
- escape_once- Escapes or encodes a string, but doesn’t include already-escaped characters. - Input- {{ "1 < 2 & 3" | escape_once }}- Output- 1 < 2 & 3
- hex_base64- Returns a base64 encoding of a hex digest, like ones returned by the - hmac_sha256filter.- Input- {{ "Customer.io" | hmac_sha256: "some_key" | hex_base64 }}- Output- bd23cyOCFrzicxM7w/ahKoJPQd0YTQlFLwXHZZ2ufVc=
- hmac_sha1- Converts a string into an hmac_sha1 hash. - Input- {{ "Customer.io" | hmac_sha1: "some_key" }}- Output- 2bdf556c9a75766f258d1e2824f6d0e31d1beedc
- hmac_sha256- Converts a string into an hmac_sha256 hash. - Input- {{ "Customer.io" | hmac_sha256: "some_key" }}- Output- 6dddb773238216bce273133bc3f6a12a824f41dd184d09452f05c7659dae7d57
- lstrip- Strips all whitespace, including tabs, spaces, and newlines, from the left side of a string. - Input- text{{ " Customer.io " | lstrip }}text- Output- textCustomer.io text
- md5- Converts a string into an md5 hash. - Input- {{ "Customer.io" | md5 }}- Output- d52b6a207bf5255c05b1d0056230617e
- newline_to_br- Replaces newline with an HTML line break. input: See this example for output. - Input- <br /> Customer.io<br /> liquid<br />
- normalize_whitespace- Replaces any occurrence of whitespace with a single space. - Input- {{ "a \n b" | normalize_whitespace }}- Output- a b
- number_of_words- Counts the number of words in text. Learn about counting Chinese-Japanese-Korean characters. - Input- {{ "Welcome to Customer.io!" | number_of_words }}- Output- 3
- pluralize- Outputs the singular or plural version of a string based on the value of a number. The first parameter is the singular string and the second parameter is the plural string. - Syntax- {{ int-val | pluralize 'singular', 'plural'}}- Input- {{ event.item_count | pluralize: 'item', 'items' }}- Output- 3 items
- prepend- Adds a string to the beginning of another string. - Input- {{ "Sufferin' succotash!" | prepend: "Sylvester: " }}- Output- Sylvester: Sufferin' succotash!
- remove_first- Removes the first occurrence of a value from a string. - Input- {{ "folks that's all, folks!" | remove_first: "folks" }}- Output- that's all folks!
- remove_last- Remove the last occurence of a string within a substring. - Input- {{ "foobarbar" | remove_last: "bar" }}- Output- foobar
- remove- Removes a value from a string. - Input- {{ "And that's all, folks!" | remove: ", folks" }}- Output- And that's all!
- replace- Find and replace values within a string. The first argument represents the value you want to replace, and the second argument is the replacement. - Syntax- {{ "String you want to replace values in" | replace: "find-str", "replace-str" }}- Input- {{ "Coyotes never catch roadrunners!" | replace: "never", "always" }}- Output- Coyotes always catch roadrunners!
- replace_first- Find and replace the first match in a string. The first argument represents the value you want to replace, and the second argument is the replacement. - Syntax- {{ "String you want to replace values in" | replace_first: "find-str", "replace-str" }}- Input- {{ "roller rocket roller skates" | replace_first: "roller", "awesome" }}- Output- awesome rocket roller skates
- replace_last- Replace the last occurence of a string within a substring. - Input- {{ "foobarbar" | replace_last: "bar", "foo" }}- Output- foobarfoo
- rstrip- Strips all whitespace, including tabs, spaces, and newlines, from the right side of a string. - Input- text{{ " Customer.io " | rstrip }}text- Output- text Customer.iotext
- sha1- Converts a string into a sha1 hash. - Input- {{ "Customer.io" | sha1 }}- Output- c197ff0ae0a41983362f35ca972c544061c54d4c
- sha256- Converts a string into a sha256 hash. - Input- {{ "Customer.io" | sha256 }}- Output- 6dddb773238216bce273133bc3f6a12a824f41dd184d09452f05c7659dae7d57
- slice- Returns the character located at the index specified in the first argument. You can also provide a second argument indicating the length of the string you want to return (if you want to return multiple characters). - If the first argument is a negative number, the index is begins from the end of the string. - Syntax- {{ "string" | slice: <req, index of char>, <optional, length of result> }}- Input- {{ "Customer.io" | slice: 3 }} {{ "Customer.io" | slice: 3, 3 }} {{ "Customer.io" | slice: '-4', 3 }}- Output- t tom r.i
- slugify- Converts a string into a lowercase URL slug. Set the mode to specify how characters and spaces should be converted. Then set a boolean value of - trueif you want to retain the original casing of the string. By default, the- slugifyfilter replaces spaces and non-alphanumeric characters with dashes and lowercases all letters.- mode - replaces - “none” - no characters - “raw” - spaces - “default” - spaces and non-alphanumeric characters - “pretty” - spaces and non-alphanumeric characters except for ._~!$&’()+,;=@ - “ascii” - spaces, non-alphanumeric, and non-ASCII characters - “latin” - like default, except Latin characters are first transliterated (e.g. àèïòü to aeiou) - Input- {{ "The _config.yml file" | slugify }} {{ "The _config.yml file" | slugify: "pretty" }} {{ "The _cönfig.yml file" | slugify: "ascii" }} {{ "The cönfig.yml file" | slugify: "latin" }} {{ "The cönfig.yml file" | slugify: "latin", true }}- Output- the-config-yml-file the-_config.yml-file the-c-nfig-yml-file the-config-yml-file The-config-yml-file
- split- Divides an input string into an array using a separator you define. This filter is often used with a for loop. - Input- {% assign rolling_stones = "Mick, Keith, Ronnie, Charlie" | split: ", " %} {% for member in rolling_stones %} {{ member }} {% endfor %}
- strip- Strips all whitespace, including tabs, spaces, and newlines, from the left and right side of a string. - Input- text{{ " Customer.io " | strip }}text- Output- Customer.io
- strip_html- Removes HTML characters from a string. - Input- {{ "Eh, what's <i>up</i>, <b>Doc</b>?" | strip_html }}- Output- Eh, what's up, Doc?
- strip_newlines- Removes line breaks (\n) from a string. - Example- {{ product.description | strip_newlines }}
- titlecase- Converts a string to title case. - Syntax- {{ 'string' | titlecase }}- Input- {{ "rocket roller skates" | titlecase }}- Output- Rocket Roller Skates
- truncate- Shortens a string to the specified number of characters, adding an ellipsis if the string is longer than the value provided. - Input- {{ "I knew I shoulda taken that left turn at Albuquerque." | truncate: 20 }}- Output- I knew I shoulda ...
- truncatewords- Shortens a string to a specified number of words, rather than characters, and adds an ellipsis if the string contains more words than the value provided. - Input- {{ "I knew I shoulda taken that left turn at Albuquerque." | truncatewords: 8 }}- Output- I knew I shoulda taken that left turn...
- upcase- Converts a string to upper case. - Syntax- {{ 'string' | upcase }}- Input- {{ 'acme' | upcase }}- Output- ACME
- uri_escape- This filter percent encodes special characters in a URI that are not reserved. - Input- {{ "https://example.com/?q=foo, \bar?" | uri_escape }}- Output- https://example.com/?q=foo,%20%08ar?
- url_decode- Decodes a string that has been encoded as a URL or has been modified by - url_encode.- Input- {{ "%27Customer.io+is+great%27" | url_decode }}- Output- Customer.io is great
- url_encode- Escapes/encodes URL-unsafe characters in a string. - Input- {{ "cool.person@example.com" | url_encode }}- Output- cool.person%40example.com
- xml_escape- Escapes text for use in XML. If you use this filter in HTML messages (i.e. not webhooks), the final output may differ due to HTML processing. - Input- {{ "Have you seen \'Learn the basics: video guide\'?" | xml_escape }}- Output- Have you read 'James & the Giant Peach'?
- Miscellaneous- These are tags that you can use to escape liquid rendering or escape rendering all together. 
- comment- This tag doesn’t show its contents, providing a way for you to leave notes inside templates for other members of your organization. - Syntax- {% comment %} Don't display me! {% endcomment %}
- default- Set a default value when one does not exist. You can use the - defaultfilter rather than checking for empty strings using- == blankor- != blank.- Example- {{ product_color | default: "red" }} {{ product_price | default: 2.99 }}
- from_json- This filter lets you create values from JSON. - from_jsonparses string-encoded (or ‘stringified’) JSON so you can reference its values with liquid. Note that you don’t need this filter for the JSON-encoded values of people, events, or objects; they are already automatically parsed.- Example- {% assign var = '{"key": "value", "number": 123, "boolean": true}' | from_json %} {{ var.key }} {{ var.number }} {{ var.boolean }}- Input- {% assign fruit = '{"type": "kiwi", "quantity": 2, "sweet": true}' | from_json %} {{ fruit.type }} {{ fruit.quantity }} {{ fruit.sweet }} {% assign greeting = '[{"greeting": "hello" }, {"greeting": "hey" }, {"greeting": "hi" }, {"greeting": "howdy" }]' | from_json %} {{ intro[0].greeting }} {{ intro[1].greeting }} {{ intro[2].greeting }} {{ intro[3].greeting }}- Output- kiwi 2 true hello hey hi howdy
- generate_uuid- Generate a UUID. - Example- {% generate_uuid %}
- json- Converts values to a JSON-encoded string (same as using - jsonify). An additional- spaceparameter can be specified to format/prettify the JSON.- Input- {% assign arr = "foo bar coo" | split: " " %} {{ arr | json: 4 }}- Output- [ "foo", "bar", "coo" ]
- raw- Temporarily disables Liquid processing. You might use this to escape tag processing if you use a conflicting syntax or you want to show raw liquid syntax in your message." - Example- {% raw %} {{This}} is displayed exactly as typed. {% endraw %}
- to_json- Outputs the json representation of the input. For example, - {{ customer | to_json }}sends all your customer data into a JSON variable.- Example- {{ customer | to_json }}
- whitespace control- You can remove whitespace before and/or after a tag using hyphens. - Input- {% assign username = "Charlie" %} Hello, {{ username -}} !- Output- Hello, Charlie!