Skip to content

Liquid filters

The 16 filters the platform registers: signature, input and output, an example, and RTL notes.

Updated 2 Sept 20263 min read
On this page

Alongside the standard LiquidJS filters (upcase, date, default, plus, size, …) the platform registers the following. The mode is strict: an unknown filter fails the render. Every {{ }} output is escaped; only the filters marked safe below emit raw HTML.

Money#

money#

Liquid
{{ product.price | money }}

Input is a money object (or a number in minor units, treated as USD). Output is safe: <span class="money-value" data-amount-minor="250000" data-currency="SYP">…</span> with the formatted text inside. The two data attributes let the browser-side currency converter re-render in the visitor's currency. Western digits, symbol before the amount, bidi-wrapped; with the arabic_numerals setting the digits become Eastern Arabic.

money_with_currency#

Liquid
{{ cart.subtotal | money_with_currency }}

The same formatted text without any markup. It does not convert with the visitor's currency; use it in alt, title and the like.

money_amount#

Liquid
{{ product.price | money_amount }}

A bare decimal string in major units ("185000" or "12.50") with no symbol and no wrapping, for machine consumers: JSON-LD and meta tags. Always Western digits.

money_major: CURRENCY#

Liquid
{{ theme_settings.free_shipping_threshold | money_major: cart.subtotal.currency }}

Formats a major-unit number the merchant typed (a free-shipping threshold, say) with the same markup money emits, so it converts with the visitor's currency too. Safe.

Media and files#

img_url: WIDTH#

Liquid
<img src="{{ product.image_url | img_url: 400 }}"
     srcset="{{ product.image_url | img_url: 400 }} 400w, {{ product.image_url | img_url: 800 }} 800w"
     sizes="(max-width: 600px) 100vw, 400px" alt="{{ product.name }}">

The image-CDN contract: on the platform media origin it emits a resized URL with the width snapped up to a fixed ladder (96, 128, 200, 400, 600, 800, 1200, 1600), automatic format and quality 72; on any other origin it adds a ?w= hint. A missing width means 400. Never build transform URLs by hand; the URL is an internal shape and the filter is the contract.

asset_url#

Liquid
<img src="{{ section.settings.image | asset_url }}" alt="{{ section.settings.image | file_alt }}">

The only way a stored file reference (an image or video setting) becomes a URL. Absolute values, schemes and .. traversal return ""; without a configured base it returns "" so the theme falls into its placeholder state.

file_alt and file_focal_style#

Liquid
<img src="{{ block.settings.image | asset_url }}" alt="{{ block.settings.image | file_alt }}"
     style="{{ block.settings.image | file_focal_style }}">

They read the alt text, focal point (object-position: X% Y%) and dominant color (background-color) set per file in the media library. The file_focal_style value is ready for a style attribute and sanitized on the server.

Text#

t#

Liquid
{{ 'product.add_to_cart' | t }}

A lookup in the current locale's table from locales/<locale>.json with dotted keys. A missing key returns the key itself and never throws.

richtext#

Liquid
<div class="prose">{{ section.settings.body | richtext }}</div>

The only way merchant-typed HTML is output. It re-sanitizes at render, whatever the source, down to p br strong em u s ul ol li h2 h3 blockquote a, with dir and text-align only on block tags, and https:/mailto:/tel:/absolute-path links. Safe. Limit 10,000 characters.

strip_html#

Liquid
{{ product.description | strip_html | truncate: 160 }}

Removes tags, decodes the basic entities and normalizes whitespace; the output is plain text escaped like any output. For descriptions in JSON-LD and meta tags.

json#

Liquid
<script type="application/ld+json">{ "name": {{ product.name | json }} }</script>

Serializes the value to JSON with <, >, & and the U+2028/U+2029 line separators escaped as \u sequences, so it is valid inside a JSON-LD block and in any context. Safe.

tel_href and wa_href#

Liquid
<a href="{{ theme_settings.phone | tel_href }}">{{ theme_settings.phone }}</a>
<a href="{{ store.whatsapp_number | wa_href }}">{{ 'contact.whatsapp' | t }}</a>

The only way a phone number becomes a link: the input is reduced to digits (with one leading + for tel:), so a merchant value can never smuggle a scheme. Empty in, empty out.

Dates#

date_localized: LOCALE#

Liquid
{{ review.created_at | date_localized: request.locale }}

A YYYY-MM-DD date as readable text: Levantine month names in Arabic, plain English otherwise. Anything not in the date shape passes through.

Neutralized#

raw#

The built-in LiquidJS raw filter is neutralized and returns its value as plain text that gets escaped; writing | raw in a template is rejected at push anyway. There is no path to raw HTML from theme or store data outside the safe filters above.