Build a Shopify store in 2 minutes.
Back to Blog
By Clyro·Developer Workflows·August 27, 2026·7 min read

Shopify Liquid Cheat Sheet: Tags, Filters and Objects (2026)

Liquid is Shopify's template language: {{ }} outputs a value, {% %} runs logic, and filters chain onto output with |. Everything else is knowing which objects exist where and which filters do what. This page is the reference, plus the constraints that are not obvious until you hit them.

Verified against Shopify's own documentation rather than written from memory, because a cheat sheet with one wrong filter name is worse than no cheat sheet.


Syntax basics

Syntax What it does
{{ product.title }} Output a value
{{- product.title -}} Output, trimming surrounding whitespace
{% if condition %} Logic tag
{%- if condition -%} Logic tag, trimming whitespace
{{ price | money }} Apply a filter
{{ a | plus: 1 | times: 2 }} Chain filters left to right
{% assign x = 'value' %} Set a variable
{% capture x %}...{% endcapture %} Set a variable from a block of output
{% comment %}...{% endcomment %} Comment

The gotchas that cost you an afternoon

These are the ones that make experienced developers stare at working-looking code.

  • No parentheses in conditions. You cannot write {% if (a and b) or c %}. Nest the if statements instead.
  • No ternary operator. There is no a ? b : c. It is always an {% if %} block, or default if you only need a fallback value.
  • contains works on strings, not objects. {% if collection.products contains product %} does not do what it looks like. It works for strings and arrays of strings only.
  • for loops stop at 50 iterations. This is a hard default. Anything larger needs {% paginate %}, and forgetting it is why a collection page silently shows 50 products.
  • render has isolated scope. A snippet cannot see the variables around it. Pass everything as a parameter: {% render 'card', product: product %}.
  • Liquid does not run inside {% stylesheet %} or {% javascript %}. Pass values through CSS custom properties on the element instead.
  • img_tag and img_url are deprecated. Use image_tag and image_url.

Tags worth knowing

Tag Use
{% liquid %} Multiple statements without repeating delimiters
{% render 'name', var: value %} Render a snippet, isolated scope
{% render 'tag' for product.tags as tag %} Render a snippet per item
{% content_for 'blocks' %} Render the theme blocks a merchant added
{% content_for 'block', type: 'slide', id: 'slide-1' %} Render one static block
{% section 'name' %} / {% sections 'group' %} Render a section or section group
{% paginate collection.products by 12 %} Required past 50 items
{% form 'product', product %} Form with the right action and hidden fields
{% schema %} JSON settings a section or block exposes to the theme editor
{% stylesheet %} / {% javascript %} Per-component CSS and JS (sections, blocks, snippets only)
{% style %} CSS that live-updates in the editor for colour settings
{% doc %} LiquidDoc header, required on snippets and static blocks
{% layout 'name' %} Choose a layout

Form types accepted by {% form %}: product, contact, customer_login, create_customer, customer_address, cart, localization, new_comment, recover_customer_password, reset_customer_password, activate_customer_password, guest_login, currency, customer, storefront_password.

Inside a for loop you get forloop.index, forloop.index0, forloop.first, forloop.last, forloop.length.

Shopify Liquid filters, by category

Category Filters
Money money, money_with_currency, money_without_currency, money_without_trailing_zeros
Images image_url, image_tag, placeholder_svg_tag, preload_tag
Array where, map, reject, find, find_index, has, first, last, sort, sort_natural, reverse, size, join, uniq, compact, concat, sum
String split, append, prepend, remove, replace, strip, truncate, upcase, downcase, capitalize, escape, handleize, url_encode, url_decode, camelize, slice, strip_html, newline_to_br, pluralize
Math plus, minus, times, divided_by, modulo, round, ceil, floor, abs, at_least, at_most
Colour color_to_hex, color_to_hsl, color_to_rgb, color_to_oklch, color_darken, color_lighten, color_mix, color_modify, color_saturate, color_brightness
HTML link_to, script_tag, stylesheet_tag, time_tag, inline_asset_content
Hosted files asset_url, file_url, global_asset_url, shopify_asset_url
Format date, json, structured_data, metafield_tag, metafield_text
Other t (translation), default, default_errors, default_pagination, font_face, font_url, payment_button

The four that come up constantly:

{{ product.price | money }}
{{ product.featured_image | image_url: width: 800 | image_tag: class: 'card__image' }}
{{ collection.products | where: 'available', true | size }}
{{ 'products.product.add_to_cart' | t }}

Objects available everywhere

shop, settings, cart, customer, request, routes, template, theme, localization, collections, pages, all_products, articles, blogs, images, linklists, metaobjects, canonical_url, page_title, page_description, handle.

Page-specific objects (product, collection, article, blog, order, search) exist only in their own templates. That is the most common cause of a value rendering blank: the object is not in scope on that template.

Theme file structure

Folder Contents
layout/ theme.liquid, the HTML shell. Must contain {{ content_for_header }} and {{ content_for_layout }}
templates/ JSON (or Liquid) files defining which sections render per page type
sections/ Full-width modules with a {% schema %}
blocks/ Smaller reusable components, also with a schema, nestable
snippets/ Fragments rendered with {% render %}, with a {% doc %} header
assets/ CSS, JS, images, fonts
config/ settings_schema.json and settings_data.json
locales/ Translations, referenced as `{{ 'key'

Is checkout.liquid still usable?

No, and the last piece of it sunset in August 2026. This matters because the dates arrived recently and a lot of advice online predates them.

  • checkout.liquid is unsupported for the Information, Shipping and Payment steps.
  • It sunset for the Thank you and Order status pages on 28 August 2025.
  • Script tags on those pages sunset for Plus stores on 28 August 2025, and for non-Plus stores on 26 August 2026.

Stores still relying on it must move to Shopify Extensions in Checkout. Shopify's admin carries a report listing your existing checkout customizations and how they map across. The details are in their upgrade documentation.

Note that checkout.liquid was only ever available to Shopify Plus merchants. On a non-Plus store, checkout customization has always been the theme editor and apps.

Writing Liquid without writing Liquid

Everything above is the reference for editing by hand, which is still the right approach for anything unusual. For the routine work, a section variant, a bundle block, a restyled product page, describing it and generating the Liquid produces the same file with a proper schema in less time than looking up the filter takes. The output is standard theme code, so this cheat sheet still applies to reading and editing it afterwards.

FAQ

What is Liquid in Shopify? Liquid is the open-source template language Shopify uses to render storefronts. It runs server-side on Shopify's infrastructure, outputs values with {{ }} and runs logic with {% %}. It has no access to a database or server-side routes of your own; it renders the data Shopify hands it.

What are Shopify Liquid filters? Filters transform output and chain with |. They cover money formatting, image URLs and tags, array operations, string manipulation, maths, colour, HTML helpers and translations. The full list by category is in the table above.

How do I output JSON in Liquid? Use the json filter: {{ product | json }} serializes an object, and it is the standard way to hand data to JavaScript. Note that theme templates and section settings are also JSON files in their own right, which is a separate thing from the filter.

Why is my Liquid loop only showing 50 items? Because for loops cap at 50 iterations by default. Wrap the loop in {% paginate collection.products by 12 %} and render {{ paginate | default_pagination }} for the controls.

Why can my snippet not see my variable? {% render %} creates an isolated scope by design. Pass the variable explicitly as a parameter: {% render 'card', product: product %}.

Does Liquid have an if/else shorthand? No ternary operator and no parentheses in conditions. Use {% if %} blocks, nested where the logic needs grouping, or the default filter when you only need a fallback value.


Keep reading: what custom Liquid is and where it lives and how Shopify theme development actually works.

Share: