Filters are one of Liquid's most powerful features, transforming raw data into polished, formatted output. While keys give you access to data and operators let you compare it, filters let you modify and format it in countless ways, all without changing the underlying values.

What are Liquid filters?

Filters are data transformation functions that modify the output of keys without changing the source data. Think of filters as a pipeline: data flows in, gets transformed, and flows out in a new format. This functional approach keeps your templates clean, predictable, and maintainable.

The syntax is builds on itself. Filters are applied using the pipe character | after a key:

{{ user.name | upcase }}

Some filters can accept parameters for more control:

{{ article.content | truncate: 100 }}

And most powerfully, filters can be chained together, with the output of one filter becoming the input of the next:

{{ user.bio | strip_html | truncate: 200 | append: "..." }}

Let's explore the different categories of filters and how to use them effectively in your notification templates.

String filters

String filters are your primary tool for text formatting and manipulation. They handle everything from capitalization to HTML stripping.

Capitalization filters

Control how text is capitalized with these filters:

  • capitalize - Capitalizes the first letter of the entire string
  • upcase - Converts all letters to uppercase
  • downcase - Converts all letters to lowercase
Data
{
  "user": {
    "name": "sarah chen",
    "company": "acme corp"
  }
}
Template
{{ user.name | capitalize }}
{{ user.name | upcase }}
{{ user.name | downcase }}
{{ user.company | capitalize }}
Output
Sarah chen
SARAH CHEN
sarah chen
Acme corp

Note that capitalize only capitalizes the first letter of the entire string, not each word.

Truncation and trimming

Shorten or clean up text with these filters:

  • truncate - Cuts text at a certain character count, optionally with custom ending
  • truncatewords - Cuts text at word boundaries for cleaner breaks
  • strip - Removes leading and trailing whitespace
Data
{
  "article": {
    "title": "The Ultimate Guide to Liquid Templating for Notifications",
    "excerpt": "   Learn how to create dynamic templates   "
  }
}
Template
{{ article.title | truncate: 30 }}
{{ article.title | truncate: 30, "..." }}
{{ article.title | truncatewords: 5 }}
{{ article.excerpt | strip }}
Output
The Ultimate Guide to Liq...
The Ultimate Guide to Liq...
The Ultimate Guide to Liquid...
Learn how to create dynamic templates

HTML and special character handling

Clean up or escape HTML content with these filters:

  • strip_html - Removes all HTML tags from a string
  • escape - Escapes special characters like &, <, > into HTML entities
Data
{
  "comment": {
    "text": "<p>This is <strong>great</strong>!</p>",
    "username": "Sarah & John"
  }
}
Template
{{ comment.text | strip_html }}
{{ comment.username | escape }}
Output
This is great!
Sarah &amp; John

String replacement and manipulation

Replace or remove parts of strings with these filters:

  • replace - Replaces all occurrences of a substring with another string
  • remove - Removes all occurrences of a substring
  • split - Splits a string into an array based on a delimiter
  • join - Joins array elements into a single string with a separator
Data
{
  "product": {
    "name": "Super Widget Pro",
    "sku": "SW-PRO-2024"
  }
}
Template
{{ product.name | replace: "Super", "Ultra" }}
{{ product.name | remove: " Pro" }}
{{ product.sku | replace: "-", "_" }}
{{ product.name | split: " " | join: "-" | downcase }}
Output
Ultra Widget Pro
Super Widget
SW_PRO_2024
super-widget-pro

String utilities

Additional useful string transformations:

  • slugify - Converts a string to URL-friendly format (lowercase, dashes instead of spaces)
  • url_encode - Encodes special characters for safe use in URLs
  • append - Adds text to the end of a string
  • prepend - Adds text to the beginning of a string
Data
{
  "url": {
    "path": "blog posts and articles",
    "params": "[email protected]"
  }
}
Template
{{ url.path | slugify }}
{{ url.params | url_encode }}
{{ "hello" | append: " world" }}
{{ "goodbye" | prepend: "Say " }}
Output
blog-posts-and-articles
user%40example.com
hello world
Say goodbye

Numeric filters

Numeric filters handle mathematical operations and number formatting.

Mathematical operations

Perform calculations directly in your templates with these filters:

  • plus - Adds a number to the input
  • minus - Subtracts a number from the input
  • times - Multiplies the input by a number
  • divided_by - Divides the input by a number
  • modulo - Returns the remainder of division
  • round - Rounds to the nearest integer or specified decimal places
Data
{
  "product": {
    "price": 99.99,
    "quantity": 3,
    "tax_rate": 0.08
  }
}
Template
Subtotal: ${{ product.price | times: product.quantity }}
Tax: ${{ product.price | times: product.quantity | times: product.tax_rate }}
Total: ${{ product.price | times: product.quantity | times: 1.08 | round: 2 }}

Price per item: ${{ 299.97 | divided_by: 3 | round: 2 }}
With $10 discount: ${{ product.price | minus: 10 }}
Price increase: ${{ product.price | plus: 20 }}
Output
Subtotal: $299.97
Tax: $23.9976
Total: $323.97

Price per item: $99.99
With $10 discount: $89.99
Price increase: $119.99

Available math filters: plus, minus, times, divided_by, modulo.

Rounding and formatting

Control decimal precision and number display with these filters:

  • round - Rounds to specified decimal places (default: 0)
  • ceil - Rounds up to the nearest integer
  • floor - Rounds down to the nearest integer
  • at_least - Ensures a number is at minimum the specified value
  • at_most - Ensures a number doesn't exceed the specified value
Data
{
  "metrics": {
    "conversion_rate": 0.15789,
    "revenue": 1234567.89,
    "percentage": 67.5
  }
}
Template
{{ metrics.conversion_rate | times: 100 | round: 2 }}%
{{ metrics.conversion_rate | times: 100 | round: 1 }}%
{{ metrics.conversion_rate | times: 100 | ceil }}%
{{ metrics.conversion_rate | times: 100 | floor }}%

Revenue: ${{ metrics.revenue | round }}
{{ metrics.percentage | at_least: 50 }}
{{ metrics.percentage | at_most: 100 }}
Output
15.79%
15.8%
16%
15%

Revenue: $1234568
67.5
67.5

The at_least and at_most filters ensure a number stays within bounds.

Array filters

Array filters help you manipulate and extract data from collections.

Extracting array elements

Access specific elements or properties with these filters:

  • first - Returns the first element of an array
  • last - Returns the last element of an array
  • map - Extracts a single property from each object in an array
  • join - Combines array elements into a single string with a separator
Data
{
  "products": [
    {
      "name": "Laptop",
      "price": 999,
      "category": "electronics"
    },
    {
      "name": "Desk",
      "price": 399,
      "category": "furniture"
    },
    {
      "name": "Chair",
      "price": 299,
      "category": "furniture"
    }
  ]
}
Template
First: {{ products | first | map: "name" }}
Last: {{ products | last | map: "name" }}
All names: {{ products | map: "name" | join: ", " }}
All prices: {{ products | map: "price" | join: " | $" | prepend: "$" }}
Output
First: Laptop
Last: Chair
All names: Laptop, Desk, Chair
All prices: $999 | $399 | $299

The map filter extracts a single property from each object in an array, creating a new array of just those values.

Sorting and filtering arrays

Organize and refine collections with these filters:

  • sort - Sorts array elements by a property or value
  • reverse - Reverses the order of array elements
  • uniq - Removes duplicate values from an array
  • size - Returns the number of elements in an array
Data
{
  "users": [
    {
      "name": "Charlie",
      "score": 85,
      "active": true
    },
    {
      "name": "Alice",
      "score": 92,
      "active": true
    },
    {
      "name": "Bob",
      "score": 78,
      "active": false
    }
  ],
  "tags": [
    "ruby",
    "python",
    "ruby",
    "javascript",
    "python"
  ]
}
Template
Alphabetical: {{ users | sort: "name" | map: "name" | join: ", " }}
By score: {{ users | sort: "score" | map: "name" | join: ", " }}
Reversed: {{ users | sort: "score" | reverse | map: "name" | join: ", " }}

Unique tags: {{ tags | uniq | sort | join: ", " }}
Tag count: {{ tags | size }}
Unique count: {{ tags | uniq | size }}
Output
Alphabetical: Alice, Bob, Charlie
By score: Bob, Charlie, Alice
Reversed: Alice, Charlie, Bob

Unique tags: javascript, python, ruby
Tag count: 5
Unique count: 3

Array operations

Combine and analyze arrays with these filters:

  • join - Combines array elements into a single string with a separator
  • size - Returns the number of elements in an array
  • compact - Removes nil values from an array
  • sort - Sorts array elements in ascending order
Data
{
  "order": {
    "items": [
      "Laptop",
      "Mouse",
      "Keyboard"
    ],
    "quantities": [
      1,
      2,
      1
    ]
  },
  "numbers": [
    5,
    2,
    8,
    1,
    9,
    3
  ]
}
Template
Item list: {{ order.items | join: ", " }}
Items with quantity: {{ order.items | join: " & " }}
Total items: {{ order.items | size }}

Compact list: {{ order.items | compact | join: ", " }}
Sorted numbers: {{ numbers | sort | join: " < " }}
Output
Item list: Laptop, Mouse, Keyboard
Items with quantity: Laptop & Mouse & Keyboard
Total items: 3

Compact list: Laptop, Mouse, Keyboard
Sorted numbers: 1 < 2 < 3 < 5 < 8 < 9

The compact filter removes nil values from arrays.

Date filters

Date filters are essential for formatting timestamps in user-friendly ways.

Basic date formatting

Format dates using strftime patterns with the date filter:

  • date - Formats timestamps using strftime format codes
Data
{
  "event": {
    "start_time": "2024-12-25T15:30:00Z",
    "created_at": "2024-01-15T09:00:00Z"
  }
}
Template
{{ event.start_time | date: "%B %d, %Y" }}
{{ event.start_time | date: "%m/%d/%Y" }}
{{ event.start_time | date: "%A, %b %d at %I:%M %p" }}
{{ event.start_time | date: "%Y-%m-%d" }}
Output
December 25, 2024
12/25/2024
Wednesday, Dec 25 at 03:30 PM
2024-12-25

Common format codes:

  • %Y - 4-digit year (2024)
  • %m - Month (01-12)
  • %d - Day (01-31)
  • %B - Full month name (December)
  • %b - Abbreviated month (Dec)
  • %A - Full day name (Wednesday)
  • %I - 12-hour format (01-12)
  • %H - 24-hour format (00-23)
  • %M - Minutes (00-59)
  • %p - AM/PM

Default values

Provide fallback values when data is missing or empty:

  • default - Returns a fallback value when the input is nil or false
Data
{
  "user": {
    "first_name": "Sarah",
    "nickname": null,
    "bio": ""
  }
}
Template
Hello, {{ user.first_name | default: "there" }}!
Nickname: {{ user.nickname | default: "No nickname set" }}
Bio: {{ user.bio | default: "No bio provided" }}
Missing: {{ user.phone | default: "Not provided" }}
Output
Hello, Sarah!
Nickname: No nickname set
Bio: 
Missing: Not provided

Note that default only applies when a value is nil or false—empty strings are still truthy, so they won't trigger the default.

Chaining filters

The real power of filters emerges when you chain them together. Each filter's output becomes the next filter's input:

Data
{
  "article": {
    "title": "understanding liquid templating",
    "content": "<p>This is a <strong>great article</strong> about Liquid that goes into extensive detail about all the features.</p>",
    "tags": [
      "liquid",
      "templating",
      "liquid",
      "notifications"
    ]
  }
}
Template
{{ article.title | capitalize | append: " - A Complete Guide" }}
{{ article.content | strip_html | truncate: 50 }}
{{ article.tags | uniq | sort | join: ", " | upcase }}
Output
Understanding liquid templating - A Complete Guide
This is a great article about Liquid that goes ...
LIQUID, NOTIFICATIONS, TEMPLATING

Practical chaining examples

Here are some real-world scenarios using filter chains:

Data
{
  "user": {
    "name": "  sarah CHEN  ",
    "signup_date": "2024-01-15T09:00:00Z"
  },
  "product": {
    "name": "Super Widget Pro",
    "price": 99.99,
    "discount": 0.15
  }
}
Template
Clean name: {{ user.name | strip | downcase | capitalize }}

Member since: {{ user.signup_date | date: "%B %Y" }}

Final price: ${{ product.price | times: 0.85 | round: 2 }}
Save: ${{ product.price | times: product.discount | round: 2 }}

URL slug: {{ product.name | downcase | replace: " ", "-" | remove: "-pro" }}
Output
Clean name: Sarah chen

Member since: January 2024

Final price: $84.99
Save: $15.00

URL slug: super-widget

Best practices for using filters

As you work with filters, make sure to keep these best practices in mind.

Order matters in filter chains

Put filters in logical sequence. For example, always strip_html before truncate:

<!-- Good: Strip HTML first, then truncate -->
{{ content | strip_html | truncate: 100 }}
 
<!-- Bad: Might truncate in middle of HTML tag -->
{{ content | truncate: 100 | strip_html }}

Use the default filter defensively

Protect against missing data by providing sensible defaults:

Welcome, {{ user.name | default: "valued customer" }}!

Format numbers for readability

Always round currency and percentages to appropriate precision:

Total: ${{ amount | round: 2 }}
Conversion: {{ rate | times: 100 | round: 1 }}%

Keep filter chains readable

For complex transformations, consider breaking across lines or using intermediate variables (which you'll learn about in the Tags chapter):

{% assign clean_content = article.content | strip_html %}
{% assign preview = clean_content | truncate: 200 %}
{{ preview }}

Filters are essential tools in your Liquid toolkit. They let you transform data on the fly, handle missing values gracefully, and format output precisely for each notification channel. Master these patterns, and you'll create templates that are both powerful and maintainable.