Shopify Liquid Cheat Sheet

A quick-reference cheat sheet for Shopify Liquid — every tag, object, and filter at a glance with copy-paste code examples. For in-depth tutorials, see the beginner's guide, filters reference, and conditionals & loops guide.

Tags

Tags ({% ... %}) control logic and flow — they don't produce visible output. For detailed examples, see our Conditionals & Loops guide.

Variable Assignment — assign & capture

assign stores a single value; capture stores a rendered block of text.

liquid
{% assign greeting = "Hello, welcome to our store!" %}
{{ greeting }}

{% assign sale_price = product.price | times: 0.8 %}
{{ sale_price | money }}

{%- comment -%} capture lets you build complex strings {%- endcomment -%}
{% capture full_name %}{{ customer.first_name }} {{ customer.last_name }}{% endcapture %}
<p>Welcome back, {{ full_name }}!</p>

Conditionals — if / elsif / else / unless

Branch with if / elsif / else; use unless for the inverse.

liquid
{% if product.available %}
  <button class="btn">Add to Cart</button>
{% elsif product.coming_soon %}
  <p>Coming Soon</p>
{% else %}
  <p>Sold Out</p>
{% endif %}

{%- comment -%} unless is the opposite of if {%- endcomment -%}
{% unless cart.item_count == 0 %}
  <a href="/cart">View Cart ({{ cart.item_count }})</a>
{% endunless %}

{%- comment -%} Combine conditions with and / or {%- endcomment -%}
{% if customer and customer.tags contains "VIP" %}
  <p>Welcome back, VIP member!</p>
{% endif %}

Conditionals — case / when

Switch-style branching — compare one variable against multiple values.

liquid
{% case product.type %}
  {% when "Shirt" %}
    <p>Check our size guide for shirts.</p>
  {% when "Pants" %}
    <p>Measured in waist and inseam.</p>
  {% when "Accessories" %}
    <p>One size fits all.</p>
  {% else %}
    <p>Contact us for sizing information.</p>
{% endcase %}

Loops — for

Iterate over arrays and ranges; access forloop.index, .first, .last, etc.

liquid
{%- comment -%} Loop through collection products {%- endcomment -%}
<ul>
{% for product in collection.products %}
  <li>
    <a href="{{ product.url }}">
      {{ product.title }}{{ product.price | money }}
    </a>
  </li>
{% endfor %}
</ul>

{%- comment -%} Limit and offset {%- endcomment -%}
{% for product in collection.products limit: 4 offset: 2 %}
  {{ product.title }}
{% endfor %}

{%- comment -%} Loop over a range {%- endcomment -%}
{% for i in (1..5) %}
  {{ i }}
{% endfor %}

{%- comment -%} forloop object {%- endcomment -%}
{% for tag in product.tags %}
  {{ tag }}{% unless forloop.last %}, {% endunless %}
{% endfor %}

Loops — tablerow, break & continue

tablerow auto-generates table rows; break exits early; continue skips an iteration.

liquid
{%- comment -%} tablerow generates <tr> and <td> tags automatically {%- endcomment -%}
<table>
{% tablerow product in collection.products cols: 3 %}
  {{ product.title }}
{% endtablerow %}
</table>

{%- comment -%} break and continue {%- endcomment -%}
{% for product in collection.products %}
  {% if product.title == "Hidden Item" %}
    {% continue %}
  {% endif %}
  {% if forloop.index > 10 %}
    {% break %}
  {% endif %}
  {{ product.title }}
{% endfor %}

Theme Tags — render, section & layout

render includes a snippet, section includes a section, layout sets the wrapper. (include is deprecated.)

liquid
{%- comment -%} Render a snippet (snippets/product-card.liquid) {%- endcomment -%}
{% render 'product-card', product: product %}

{%- comment -%} Render a snippet for every item in a collection {%- endcomment -%}
{% for product in collection.products %}
  {% render 'product-card', product: product, show_badge: true %}
{% endfor %}

{%- comment -%} Include a section {%- endcomment -%}
{% section 'featured-collection' %}
{% section 'newsletter-signup' %}

{%- comment -%} Use a specific layout or none {%- endcomment -%}
{% layout 'full-width' %}
{% layout none %}

{%- comment -%} include is deprecated — use render instead {%- endcomment -%}
{% include 'old-snippet' %}

Other Tags — comment, raw & paginate

comment hides output, raw disables Liquid processing, and paginate splits collections across pages.

liquid
{% comment %} This will not appear in the output {% endcomment %}

{%- comment -%} Whitespace-trimmed version {%- endcomment -%}

{%- comment -%} raw outputs Liquid code literally {%- endcomment -%}
{% raw %}
  The assign tag looks like: {% assign my_var = "hello" %}
  Objects use double braces: {{ product.title }}
{% endraw %}

{%- comment -%} paginate a collection — 12 items per page {%- endcomment -%}
{% paginate collection.products by 12 %}
  {% for product in collection.products %}
    {{ product.title }}
  {% endfor %}

  {{ paginate | default_pagination }}
{% endpaginate %}

Objects

Objects ({{ ... }}) output data from your store. Access properties with dot notation.

product

Available on product pages and in collection loops — holds all data for a single product.

liquid
<h1>{{ product.title }}</h1>
<p class="price">{{ product.price | money }}</p>
<div class="description">{{ product.description }}</div>

{%- comment -%} Product images {%- endcomment -%}
{% for image in product.images %}
  <img src="{{ image | img_url: 'medium' }}" alt="{{ image.alt | escape }}" />
{% endfor %}

{%- comment -%} Variants {%- endcomment -%}
<select name="id">
{% for variant in product.variants %}
  <option value="{{ variant.id }}">
    {{ variant.title }}{{ variant.price | money }}
  </option>
{% endfor %}
</select>

{%- comment -%} Other properties {%- endcomment -%}
<p>Vendor: {{ product.vendor }}</p>
<p>Type: {{ product.type }}</p>
<p>URL: {{ product.url }}</p>
<p>Available: {{ product.available }}</p>

{%- comment -%} Tags {%- endcomment -%}
{% for tag in product.tags %}
  <span class="badge">{{ tag }}</span>
{% endfor %}

collection

Represents a group of products. Available on collection pages and accessible by handle.

liquid
<h1>{{ collection.title }}</h1>
<p>{{ collection.description }}</p>
<p>{{ collection.all_products_count }} products</p>

{% for product in collection.products %}
  <a href="{{ product.url | within: collection }}">
    {{ product.title }}
  </a>
{% endfor %}

{%- comment -%} Access a specific collection by handle {%- endcomment -%}
{% assign featured = collections["featured"] %}
<a href="{{ featured.url }}">{{ featured.title }}</a>

cart

The current shopping cart — items, totals, and notes.

liquid
<p>Items in cart: {{ cart.item_count }}</p>
<p>Total: {{ cart.total_price | money }}</p>

{% for item in cart.items %}
  <div class="cart-item">
    <img src="{{ item.image | img_url: 'small' }}" alt="{{ item.title | escape }}" />
    <p>{{ item.product.title }}</p>
    <p>Qty: {{ item.quantity }} × {{ item.price | money }}</p>
    <p>Line total: {{ item.line_price | money }}</p>
  </div>
{% endfor %}

{%- comment -%} Cart note {%- endcomment -%}
{% if cart.note != blank %}
  <p>Note: {{ cart.note }}</p>
{% endif %}

customer

Available when logged in — always check if customer before use.

liquid
{% if customer %}
  <p>Hello, {{ customer.first_name }} {{ customer.last_name }}!</p>
  <p>Email: {{ customer.email }}</p>

  <h3>Order History</h3>
  {% for order in customer.orders %}
    <p>
      {{ order.name }}{{ order.total_price | money }}{{ order.created_at | date: "%B %d, %Y" }}
    </p>
  {% endfor %}

  {%- comment -%} Customer tags {%- endcomment -%}
  {% if customer.tags contains "wholesale" %}
    <p>Wholesale pricing applied.</p>
  {% endif %}
{% else %}
  <a href="/account/login">Log In</a>
{% endif %}

shop

Globally available — store name, URL, currency, and description.

liquid
<title>{{ page_title }} | {{ shop.name }}</title>
<meta name="description" content="{{ shop.description | escape }}" />

<p>Store URL: {{ shop.url }}</p>
<p>Currency: {{ shop.currency }}</p>
<p>Store name: {{ shop.name }}</p>

page

A single CMS page (e.g. About Us, FAQ).

liquid
<h1>{{ page.title }}</h1>
<div class="page-content">
  {{ page.content }}
</div>
<a href="{{ page.url }}">Permalink</a>

article & blog

article is a blog post; blog is the blog itself.

liquid
{%- comment -%} Blog listing {%- endcomment -%}
<h1>{{ blog.title }}</h1>
{% for article in blog.articles %}
  <article>
    <h2>
      <a href="{{ article.url }}">{{ article.title }}</a>
    </h2>
    <p>By {{ article.author }} on {{ article.published_at | date: "%B %d, %Y" }}</p>
    <div>{{ article.excerpt_or_content }}</div>
    <p>{{ article.comments_count }} comments</p>
  </article>
{% endfor %}

{%- comment -%} Article tags {%- endcomment -%}
{% for tag in article.tags %}
  <a href="{{ blog.url }}/tagged/{{ tag | handleize }}">{{ tag }}</a>
{% endfor %}

linklists & linklist

Navigation menus accessed by handle. Links can nest for dropdowns.

liquid
{%- comment -%} Main navigation {%- endcomment -%}
<nav>
{% for link in linklists.main-menu.links %}
  <a href="{{ link.url }}">{{ link.title }}</a>

  {%- comment -%} Nested dropdown links {%- endcomment -%}
  {% if link.links.size > 0 %}
    <ul>
    {% for child in link.links %}
      <li>
        <a href="{{ child.url }}">{{ child.title }}</a>
      </li>
    {% endfor %}
    </ul>
  {% endif %}
{% endfor %}
</nav>

{%- comment -%} Footer navigation {%- endcomment -%}
{% for link in linklists.footer.links %}
  <a href="{{ link.url }}">{{ link.title }}</a>
{% endfor %}

Filters

Filters transform output via the pipe | and can be chained. For detailed explanations, see our Filters Reference.

String Filters

Transform and format text.

liquid
{%- comment -%} Case conversion {%- endcomment -%}
{{ "hello world" | upcase }}          <!-- HELLO WORLD -->
{{ "HELLO WORLD" | downcase }}        <!-- hello world -->

{%- comment -%} Whitespace {%- endcomment -%}
{{ "  hello  " | strip }}            <!-- hello -->

{%- comment -%} Replace {%- endcomment -%}
{{ product.title | replace: "Old", "New" }}

{%- comment -%} Append and prepend {%- endcomment -%}
{{ "world" | prepend: "hello " }}       <!-- hello world -->
{{ "hello" | append: " world" }}       <!-- hello world -->

{%- comment -%} Truncate {%- endcomment -%}
{{ product.description | truncate: 100 }}
{{ product.title | truncate: 20, "..." }}

{%- comment -%} Split into array {%- endcomment -%}
{% assign words = "one,two,three" | split: "," %}
{{ words[0] }}  <!-- one -->

{%- comment -%} URL encoding {%- endcomment -%}
{{ "hello world & more" | url_encode }}  <!-- hello+world+%26+more -->

{%- comment -%} Handle (slug) {%- endcomment -%}
{{ "My Product Title" | handleize }}  <!-- my-product-title -->

{%- comment -%} Strip HTML tags {%- endcomment -%}
{{ product.description | strip_html }}

{%- comment -%} Convert newlines to <br> tags {%- endcomment -%}
{{ product.description | newline_to_br }}

Number Filters

Arithmetic and formatting. Prices are in cents — use money to display them.

liquid
{%- comment -%} Basic arithmetic {%- endcomment -%}
{{ 5 | plus: 3 }}          <!-- 8 -->
{{ 10 | minus: 4 }}         <!-- 6 -->
{{ 3 | times: 4 }}         <!-- 12 -->
{{ 20 | divided_by: 3 }}    <!-- 6 (integer division) -->
{{ 20.0 | divided_by: 3 }}  <!-- 6.666... (float division) -->
{{ 7 | modulo: 3 }}        <!-- 1 -->

{%- comment -%} Rounding {%- endcomment -%}
{{ 4.3 | ceil }}          <!-- 5 -->
{{ 4.7 | floor }}         <!-- 4 -->
{{ 4.567 | round: 2 }}     <!-- 4.57 -->

{%- comment -%} Money formatting (prices are in cents) {%- endcomment -%}
{{ product.price | money }}                   <!-- $25.00 -->
{{ product.price | money_with_currency }}     <!-- $25.00 USD -->

{%- comment -%} Practical: calculate a 20% discount {%- endcomment -%}
{% assign discount = product.price | times: 0.8 %}
<p>Was {{ product.price | money }} — Now {{ discount | money }}</p>

Array Filters

Sort, filter, transform, and extract data from arrays.

liquid
{%- comment -%} Join array into a string {%- endcomment -%}
{{ product.tags | join: ", " }}  <!-- tag1, tag2, tag3 -->

{%- comment -%} First and last {%- endcomment -%}
{{ product.images | first }}
{{ product.images | last }}

{%- comment -%} Size (count) {%- endcomment -%}
{{ product.images | size }}  <!-- 5 -->

{%- comment -%} Sort {%- endcomment -%}
{% assign sorted = collection.products | sort: "title" %}

{%- comment -%} Reverse {%- endcomment -%}
{% assign reversed = collection.products | reverse %}

{%- comment -%} Map — extract a single property from each item {%- endcomment -%}
{% assign titles = collection.products | map: "title" %}
{{ titles | join: ", " }}

{%- comment -%} Where — filter items by a property value {%- endcomment -%}
{% assign available = collection.products | where: "available", true %}
{% for product in available %}
  {{ product.title }}
{% endfor %}

{%- comment -%} Concat — merge two arrays {%- endcomment -%}
{% assign all_tags = product.tags | concat: collection.tags %}

{%- comment -%} Uniq — remove duplicates {%- endcomment -%}
{% assign unique_tags = all_tags | uniq %}

Date Filters

Format dates with strftime-style tokens.

liquid
{%- comment -%} Common date formats {%- endcomment -%}
{{ article.published_at | date: "%B %d, %Y" }}      <!-- January 15, 2025 -->
{{ article.published_at | date: "%b %d, %Y" }}      <!-- Jan 15, 2025 -->
{{ article.published_at | date: "%m/%d/%Y" }}       <!-- 01/15/2025 -->
{{ article.published_at | date: "%Y-%m-%d" }}       <!-- 2025-01-15 -->
{{ article.published_at | date: "%I:%M %p" }}       <!-- 02:30 PM -->

{%- comment -%} Current time with "now" {%- endcomment -%}
{{ "now" | date: "%Y" }}  <!-- current year, e.g. 2025 -->

{%- comment -%} Format string reference:
  %Y = 4-digit year    %m = month (01-12)   %d = day (01-31)
  %B = full month name  %b = short month     %A = full weekday
  %H = hour (24h)       %I = hour (12h)      %M = minute
  %S = second           %p = AM/PM           %Z = timezone
{%- endcomment -%}

{%- comment -%} Practical: show relative order date {%- endcomment -%}
<time datetime="{{ order.created_at | date: '%Y-%m-%d' }}">
  {{ order.created_at | date: "%B %d, %Y" }}
</time>

URL Filters

Generate asset URLs, image URLs, link tags, and extract URL parameters.

liquid
{%- comment -%} Asset URLs — reference files in the assets/ folder {%- endcomment -%}
{{ 'style.css' | asset_url }}
<!-- //cdn.shopify.com/s/files/.../assets/style.css?v=... -->

<link rel="stylesheet" href="{{ 'theme.css' | asset_url }}" />
<script src="{{ 'app.js' | asset_url }}"></script>

{%- comment -%} Image URLs with size {%- endcomment -%}
{{ product.featured_image | img_url: '100x100' }}
{{ product.featured_image | img_url: 'medium' }}
{{ product.featured_image | img_url: 'large' }}
{{ product.featured_image | img_url: '1024x1024' }}

{%- comment -%} Practical: responsive image {%- endcomment -%}
<img
  src="{{ product.featured_image | img_url: '480x' }}"
  srcset="
    {{ product.featured_image | img_url: '320x' }} 320w,
    {{ product.featured_image | img_url: '480x' }} 480w,
    {{ product.featured_image | img_url: '768x' }} 768w
  "
  alt="{{ product.featured_image.alt | escape }}"
/>

{%- comment -%} link_to — generates a full <a> tag {%- endcomment -%}
{{ "View all products" | link_to: collections.all.url }}
<!-- <a href="/collections/all">View all products</a> -->

{%- comment -%} Extract query parameter from current URL {%- endcomment -%}
{% assign sort = canonical_url | url_param_value: "sort_by" %}
{% if sort == "price-ascending" %}
  <p>Sorted by price: low to high</p>
{% endif %}

Related Guides

We're building an AI Liquid code generator — join the waitlist.

Get early access when we launch. No spam, just one email.