Developer reference

Shopify Liquid Cheat Sheet

Interactive quick reference for tags, filters, objects, and schema. Search or browse by category. Need to turn HTML into sections? Read our HTML to Liquid converter guide.

HTML to Liquid converter guide →

Most used

Most Used

Render Section Setting

Outputs a text or basic setting value from the section schema.

When to use:Use this whenever you want to display data that a merchant has entered in the Theme Editor for the current section.
Make sure to escape plain text using {{ section.settings.title | escape }} to prevent malicious code injection.
{{ section.settings.title }}
Most Used

Render Image (Modern)

The modern, performant way to render an image picker setting with automatic WebP support.

When to use:When outputting an image selected by the merchant. Never use the deprecated img_url filter.
Read our Image Optimization Guide for more speed tips.
{{ section.settings.image | image_url: width: 800 | image_tag: loading: 'lazy', class: 'my-custom-class' }}
Most Used

Basic For Loop

Loops through section blocks to render repeated content like a gallery or FAQ.

When to use:Use this to create scalable sections where merchants can add/remove items freely.
Always include block.shopify_attributes inside the loop so the Theme Editor can hook into the block for live editing.
{% for block in section.blocks %}
  <div {{ block.shopify_attributes }}>
    {{ block.settings.heading }}
  </div>
{% endfor %}

All snippets

Most Used

Render Section Setting

Outputs a text or basic setting value from the section schema.

When to use:Use this whenever you want to display data that a merchant has entered in the Theme Editor for the current section.
Make sure to escape plain text using {{ section.settings.title | escape }} to prevent malicious code injection.
{{ section.settings.title }}
Most Used

Render Image (Modern)

The modern, performant way to render an image picker setting with automatic WebP support.

When to use:When outputting an image selected by the merchant. Never use the deprecated img_url filter.
Read our Image Optimization Guide for more speed tips.
{{ section.settings.image | image_url: width: 800 | image_tag: loading: 'lazy', class: 'my-custom-class' }}
Most Used

Basic For Loop

Loops through section blocks to render repeated content like a gallery or FAQ.

When to use:Use this to create scalable sections where merchants can add/remove items freely.
Always include block.shopify_attributes inside the loop so the Theme Editor can hook into the block for live editing.
{% for block in section.blocks %}
  <div {{ block.shopify_attributes }}>
    {{ block.settings.heading }}
  </div>
{% endfor %}
Product

Product Title

Outputs the title of the current product.

When to use:On product templates, or inside a loop over collection.products.
{{ product.title }}
Product

Product Price Formatting

Formats the product price according to the store's currency settings.

When to use:Whenever you display a price. Use money_without_trailing_zeros if you want cleaner rounded numbers.
{{ product.price | money }}
<!-- Compare at price -->
{{ product.compare_at_price | money }}
Product

Product Vendor & Type

Outputs the vendor (brand) and product type.

When to use:Useful for displaying brand names above the title or filtering.
{{ product.vendor }}
{{ product.type }}
Product

Product Tags Loop

Iterates through all tags attached to a product.

When to use:Great for rendering 'New' or 'Sale' badges dynamically.
{% for tag in product.tags %}
  <span class="badge">{{ tag }}</span>
{% endfor %}
Product

First Available Variant

Gets the first variant that is currently in stock.

When to use:Use this to determine the default price to show on page load before a user selects a size/color.
{% assign current_variant = product.selected_or_first_available_variant %}
{{ current_variant.price | money }}
Product

Product Media Gallery

Loops through all images, videos, and 3D models attached to a product.

When to use:When building custom product page image galleries or sliders.
{% for media in product.media %}
  {% render 'media', media: media %}
{% endfor %}
Product

Product Description

Outputs the main product description HTML from the admin.

When to use:On product pages below the title and price. Wrap in a .rte class for consistent typography.
Use strip_html only if you need plain text previews—not on the full product page.
<div class="product-description rte">
  {{ product.description }}
</div>
Product

Product Description (Plain Preview)

Strips HTML tags for short previews in cards or search results.

When to use:Product cards, collection grids, or quick-view snippets where full HTML is too heavy.
{{ product.description | strip_html | truncate: 120 }}
Product

Product URL

The canonical URL path for the current product.

When to use:Linking to product pages from featured sections, blogs, or custom landing pages.
<a href="{{ product.url }}">{{ product.title }}</a>
Product

Check Product Availability

Returns true if at least one variant can be purchased.

When to use:Before showing add-to-cart buttons or urgency messaging.
{% if product.available %}
  <button type="submit" name="add">Add to cart</button>
{% else %}
  <button disabled>Sold out</button>
{% endif %}
Product

Featured Product Image

Renders the product's main image using modern Shopify image filters.

When to use:Product cards and hero images. Use loading: 'eager' only for above-the-fold images.
Read related guide →
{% if product.featured_image %}
  {{ product.featured_image | image_url: width: 1200 | image_tag: loading: 'eager', alt: product.featured_image.alt | escape }}
{% endif %}
Product

Featured Media (OS 2.0)

Accesses the primary media object, which may be an image, video, or 3D model.

When to use:Modern themes that support video and 3D on the product page.
{% if product.featured_media %}
  {% render 'product-media', media: product.featured_media %}
{% endif %}
Product

Loop All Variants

Iterates every variant (size, color, etc.) on a product.

When to use:Building custom variant pickers or JSON data for JavaScript.
{% for variant in product.variants %}
  <option value="{{ variant.id }}" {% unless variant.available %}disabled{% endunless %}>
    {{ variant.title }} — {{ variant.price | money }}
  </option>
{% endfor %}
Product

Variant SKU & Barcode

Outputs inventory identifiers for the selected or first available variant.

When to use:B2B catalogs, wholesale pages, or fulfillment detail modals.
{% assign v = product.selected_or_first_available_variant %}
<p>SKU: {{ v.sku }}</p>
<p>Barcode: {{ v.barcode }}</p>
Product

Product Options (Size, Color)

Loops option names and values—for example Color: Red, Blue.

When to use:Custom variant UI when you are not using Shopify's default product form.
{% for option in product.options_with_values %}
  <fieldset>
    <legend>{{ option.name }}</legend>
    {% for value in option.values %}
      <label><input type="radio" name="{{ option.name }}" value="{{ value }}"> {{ value }}</label>
    {% endfor %}
  </fieldset>
{% endfor %}
Product

Check for Specific Tag

Shows content only when a product has a given tag.

When to use:Sale badges, new-arrival labels, or hiding features for certain product types.
{% if product.tags contains 'sale' %}
  <span class="badge badge--sale">On sale</span>
{% endif %}
Collection

Collection Title & Description

Outputs the collection's title and its rich text description.

When to use:On the collection template hero banner.
<h1>{{ collection.title }}</h1>
<div>{{ collection.description }}</div>
Collection

Loop Collection Products

Iterates through products in a specific collection.

When to use:When building product grids. The 'else' block renders if the collection is empty.
{% for product in collection.products %}
  <h2>{{ product.title }}</h2>
{% else %}
  <p>No products found.</p>
{% endfor %}
Collection

Paginate Collection

Required for collections with more than 50 products.

When to use:Always use pagination on collection pages. Shopify limits standard loops to 50 items.
Read related guide →
{% paginate collection.products by 12 %}
  {% for product in collection.products %}
    <!-- Render product card -->
  {% endfor %}
  {{ paginate | default_pagination }}
{% endpaginate %}
Collection

Collection URL & Handle

Builds links and CSS hooks from the collection object.

When to use:Breadcrumbs, collection cards, and filtering UI.
<a href="{{ collection.url }}">{{ collection.title }}</a>
<!-- Handle for data attributes -->
data-collection="{{ collection.handle }}"
Collection

Collection Product Count

Shows how many products belong to the collection.

When to use:Collection headers, filters sidebar, or SEO-friendly collection intros.
<p>{{ collection.products_count }} products</p>
Collection

Collection Featured Image

Renders the image uploaded for the collection in the admin.

When to use:Collection banner heroes and navigation tiles.
{% if collection.image %}
  {{ collection.image | image_url: width: 1600 | image_tag: loading: 'lazy', alt: collection.title | escape }}
{% endif %}
Collection

Collection from Section Setting

Loops products from a collection the merchant picked in the theme editor.

When to use:Homepage featured collection rows driven by a collection picker setting.
{% assign featured = section.settings.collection %}
{% if featured != blank %}
  {% for product in featured.products limit: section.settings.limit %}
    {% render 'product-card', product: product %}
  {% endfor %}
{% endif %}
Blog & Article

Paginate Blog Articles

Pagination works for blogs too—not only collections.

When to use:Blog listing templates with more than a handful of posts.
{% paginate blog.articles by 6 %}
  {% for article in blog.articles %}
    <h2><a href="{{ article.url }}">{{ article.title }}</a></h2>
  {% endfor %}
  {{ paginate | default_pagination }}
{% endpaginate %}
Cart

Cart Item Count & Total

Displays the total number of items and the total price of the cart.

When to use:In the header cart icon or cart drawer header.
{{ cart.item_count }} items
{{ cart.total_price | money_with_currency }}
Cart

Cart Items Loop

Loops through all items currently in the cart.

When to use:When building custom cart pages or ajax cart drawers.
{% for item in cart.items %}
  <img src="{{ item.image | image_url: width: 100 }}">
  <h3>{{ item.product.title }}</h3>
  <p>Qty: {{ item.quantity }}</p>
  <p>{{ item.final_line_price | money }}</p>
{% endfor %}
Cart

Empty Cart Check

Shows different markup when the cart has zero items.

When to use:Cart drawer, cart page, and mini-cart components.
{% if cart.item_count == 0 %}
  <p>Your cart is empty.</p>
  <a href="{{ routes.all_products_collection_url }}">Continue shopping</a>
{% else %}
  <!-- cart items -->
{% endif %}
Cart

Cart Subtotal vs Total

Displays line totals; cart.total_price includes discounts where applicable.

When to use:Cart summary sidebars. Pair with shipping/tax messaging at checkout.
<p>Subtotal: {{ cart.total_price | money }}</p>
<p>Items: {{ cart.item_count }}</p>
Cart

Line Item Variant Title

Shows the variant name (e.g. Size M / Color Black) for each cart line.

When to use:Cart drawers and order review lists so customers confirm the right variant.
{% for item in cart.items %}
  <p class="line-item__variant">{{ item.variant.title }}</p>
{% endfor %}
Cart

Line Item Properties

Outputs custom properties added at add-to-cart (engraving, gift message, etc.).

When to use:Personalized products, upload fields, or B2B purchase order numbers.
{% for item in cart.items %}
  {% unless item.properties == empty %}
    <ul>
      {% for property in item.properties %}
        <li>{{ property.first }}: {{ property.last }}</li>
      {% endfor %}
    </ul>
  {% endunless %}
{% endfor %}
Cart

Cart Note Field

Outputs the optional note customers leave for the store.

When to use:Cart page or drawer when you want delivery or gift instructions.
<textarea name="note">{{ cart.note }}</textarea>
Customer

Check if Logged In

Checks if a customer is currently logged into their account.

When to use:For dynamic header links or gating wholesale content.
{% if customer %}
  Welcome back, {{ customer.first_name }}!
  <a href="{{ routes.account_url }}">My Account</a>
{% else %}
  <a href="{{ routes.account_login_url }}">Log In</a>
{% endif %}
Customer

Customer Full Name

Outputs first and last name, or a combined name when available.

When to use:Account dashboards, welcome messages, and order history headers.
{{ customer.name }}
<!-- Or separately -->
{{ customer.first_name }} {{ customer.last_name }}
Customer

Customer Account Links

Uses Shopify route objects for correct login, register, and logout URLs.

When to use:Header navigation and mobile menus—never hardcode /account/login paths.
<a href="{{ routes.account_url }}">Account</a>
<a href="{{ routes.account_login_url }}">Log in</a>
<a href="{{ routes.account_register_url }}">Create account</a>
<a href="{{ routes.account_logout_url }}">Log out</a>
Customer

Customer Email & Orders

Shows account email and loops recent orders on the account page.

When to use:Account landing pages and loyalty program sections.
<p>{{ customer.email }}</p>
{% for order in customer.orders limit: 5 %}
  <a href="{{ order.customer_url }}">Order {{ order.name }} — {{ order.total_price | money }}</a>
{% endfor %}
Customer

Default Customer Address

Outputs the customer's default shipping address when set.

When to use:Checkout shortcuts or account profile summaries.
{% if customer.default_address %}
  <address>
    {{ customer.default_address.address1 }}<br>
    {{ customer.default_address.city }}, {{ customer.default_address.province_code }} {{ customer.default_address.zip }}
  </address>
{% endif %}
Blog & Article

Blog Articles Loop

Loops through articles in a specific blog (e.g., 'news').

When to use:To display recent news on the homepage.
{% for article in blogs['news'].articles limit: 3 %}
  <h2>{{ article.title }}</h2>
  <p>{{ article.excerpt_or_content | truncatewords: 20 }}</p>
  <a href="{{ article.url }}">Read more</a>
{% endfor %}
Blog & Article

Article Title & URL

Standard article heading and permalink on article templates.

When to use:article.liquid template header area.
<h1>{{ article.title }}</h1>
<p><time datetime="{{ article.published_at | date: '%Y-%m-%d' }}">{{ article.published_at | date: format: 'abbreviated_date' }}</time></p>
Blog & Article

Article Content

Outputs the full article body HTML from the blog editor.

When to use:Main column on article pages. Use .rte for typography styles.
<div class="article-content rte">
  {{ article.content }}
</div>
Blog & Article

Article Author & Image

Shows byline and featured image when present.

When to use:Editorial layouts and magazine-style blog templates.
{% if article.image %}
  {{ article.image | image_url: width: 1200 | image_tag: loading: 'lazy', alt: article.title | escape }}
{% endif %}
<p>By {{ article.author }}</p>
Blog & Article

Current Blog Title

Outputs the name of the blog handle you are viewing (News, Journal, etc.).

When to use:blog.liquid listing page hero and meta sections.
<h1>{{ blog.title }}</h1>
<p>{{ blog.articles_count }} articles</p>
Blog & Article

Loop Articles on Blog Template

Standard loop when you are already on a blog listing template.

When to use:blog.liquid—use blog.articles instead of blogs['handle'].articles.
{% for article in blog.articles %}
  <article>
    <h2><a href="{{ article.url }}">{{ article.title }}</a></h2>
    <p>{{ article.excerpt | default: article.content | strip_html | truncate: 160 }}</p>
  </article>
{% endfor %}
Theme Settings

Global Theme Settings

Access settings defined in settings_schema.json (globally available).

When to use:For branding colors, typography choices, or global social media links.
{{ settings.color_primary }}
{{ settings.social_instagram_link }}
Theme Settings

Richtext Output

Outputs a richtext schema setting properly.

When to use:When you want merchants to be able to add bolding, italics, or links to text.
<div class="rte">
  {{ section.settings.text }}
</div>
Theme Settings

Select Setting Condition

Using a dropdown select setting to change layout logic.

When to use:For layout controls like text alignment or image positioning.
{% if section.settings.alignment == 'center' %}
  <div class="text-center">
{% else %}
  <div class="text-left">
{% endif %}
Theme Settings

Block Settings

Reads values from an individual block inside a section loop.

When to use:Sliders, FAQs, icon grids—any repeatable block defined in schema.
Read related guide →
{% for block in section.blocks %}
  <div {{ block.shopify_attributes }}>
    <h3>{{ block.settings.heading }}</h3>
    <p>{{ block.settings.text }}</p>
  </div>
{% endfor %}
Theme Settings

Image Picker Setting

Outputs an image from a section or block image_picker field.

When to use:Hero banners, logos, and background images controlled by merchants.
Read related guide →
{% if section.settings.image != blank %}
  {{ section.settings.image | image_url: width: 800 | image_tag: loading: 'lazy', alt: section.settings.image.alt | escape }}
{% endif %}
Theme Settings

Range Setting (Spacing)

Uses a numeric range value from schema—often for padding or font size.

When to use:When merchants need a slider control instead of typing raw pixel values.
Read related guide →
<div style="padding-top: {{ section.settings.padding }}px;">
  <!-- content -->
</div>
Theme Settings

Checkbox Toggle

Shows or hides elements based on a true/false schema checkbox.

When to use:Optional UI pieces—badges, secondary buttons, or extra metadata rows.
{% if section.settings.show_vendor %}
  <p class="product-card__vendor">{{ product.vendor }}</p>
{% endif %}
Theme Settings

Color Setting

Applies a merchant-selected color from the theme editor.

When to use:Section-level branding. Prefer CSS variables in theme settings for global palettes.
<div style="background-color: {{ section.settings.bg_color }};">
  {{ section.settings.heading }}
</div>
Theme Settings

URL Setting Link

Builds a CTA from a url-type schema setting.

When to use:Banner buttons, promo bars, and footer CTAs merchants can update without code.
{% if section.settings.button_link != blank %}
  <a href="{{ section.settings.button_link }}" class="btn">
    {{ section.settings.button_label | escape }}
  </a>
{% endif %}
Metafields

Product Metafield

Outputs a custom metafield attached to a product.

When to use:To display custom data like materials, sizing charts, or care instructions.
Read our Metafields Tutorial to learn how to create these in the admin.
{{ product.metafields.custom.care_instructions }}
Metafields

Render Rich Text Metafield

Safely renders HTML from a Rich Text Metafield.

When to use:If the metafield type is 'Rich text', you MUST use the metafield_tag filter to render it.
{{ product.metafields.custom.details | metafield_tag }}
Metafields

Check Metafield Before Output

Avoids empty wrappers when a metafield has no value.

When to use:Any optional custom field on product, collection, or article pages.
{% if product.metafields.custom.size_chart != blank %}
  <div class="size-chart">
    {{ product.metafields.custom.size_chart | metafield_tag }}
  </div>
{% endif %}
Metafields

Collection Metafield

Outputs custom data attached to a collection.

When to use:Extra collection copy, lookbook embeds, or merchandising notes below the title.
Read related guide →
{{ collection.metafields.custom.seo_intro }}
Metafields

Article Metafield

Displays custom fields on blog posts—reading time, series, etc.

When to use:Editorial blogs that need structured data beyond title and body.
{% if article.metafields.custom.reading_time != blank %}
  <span>{{ article.metafields.custom.reading_time }} min read</span>
{% endif %}
Metafields

Shop-Level Metafield

Reads metafields on the shop object for global theme data.

When to use:Store-wide banners or compliance text managed outside individual sections.
{{ shop.metafields.custom.announcement_text }}
Loops

For Loop with Limit

Loops exactly X number of times.

When to use:To show a preview of a collection, like a 'Featured Products' row.
{% for product in collection.products limit: 4 %}
  {{ product.title }}
{% endfor %}
Loops

Forloop Object (Index)

Access the current iteration number of a loop.

When to use:Useful for adding unique IDs or logic based on position (e.g. adding a 'active' class to the first slider dot).
{% for block in section.blocks %}
  Item number {{ forloop.index }} of {{ forloop.length }}
  {% if forloop.first %}This is the first!{% endif %}
  {% if forloop.last %}This is the last!{% endif %}
{% endfor %}
Loops

Loop with Offset

Skips the first N items—handy when the first product is featured elsewhere.

When to use:Homepage grids where item 1 is shown in a hero and items 2–5 fill a row.
Read related guide →
{% for product in collection.products limit: 4 offset: 1 %}
  {% render 'product-card', product: product %}
{% endfor %}
Loops

Reversed Loop

Iterates from last to first without mutating the original array.

When to use:Timelines, stacked cards, or any UI where newest content should appear first.
{% for block in section.blocks reversed %}
  {{ block.settings.heading }}
{% endfor %}
Loops

Assign Before Loop

Stores a collection or product in a variable for cleaner templates.

When to use:When the same list is referenced multiple times in one section.
{% assign featured_products = section.settings.collection.products %}
{% for product in featured_products limit: 8 %}
  {{ product.title }}
{% endfor %}
Loops

Tablerow for Grid Layouts

Opens and closes HTML rows every N columns automatically.

When to use:Legacy table-based grids. Most modern themes use CSS grid with a standard for loop instead.
<table>
  {% tablerow product in collection.products cols: 3 %}
    <td>{{ product.title }}</td>
  {% endtablerow %}
</table>
Conditions

If / Elsif / Else

Standard conditional logic.

When to use:Whenever you need to branch logic based on variables.
{% if product.price < 5000 %}
  Budget Friendly
{% elsif product.price < 10000 %}
  Mid-Range
{% else %}
  Premium
{% endif %}
Conditions

Unless (If Not)

The opposite of 'if'. Executes if the condition is false.

When to use:Cleaner to read than {% if product.available == false %}.
{% unless product.available %}
  Sold Out!
{% endunless %}
Conditions

Case / When

A switch statement for cleaner multiple-condition checks.

When to use:When checking a single variable against many possible values.
{% case section.settings.color_scheme %}
  {% when 'dark' %}
    <div class="bg-black text-white">
  {% when 'light' %}
    <div class="bg-white text-black">
  {% else %}
    <div class="bg-gray-100">
{% endcase %}
Conditions

Check if Blank

Liquid treats empty strings, false, and nil as falsy in conditionals.

When to use:Before rendering optional settings so you do not output empty headings or broken images.
{% if section.settings.heading != blank %}
  <h2>{{ section.settings.heading | escape }}</h2>
{% endif %}
Conditions

Contains Operator

Checks whether a string or array includes a value.

When to use:Tags, handles, and cart attribute-based feature flags.
{% if product.tags contains 'featured' %}
  <span class="badge">Featured</span>
{% endif %}

{% if cart.attributes['gift'] == 'yes' %}
  <!-- gift wrap UI -->
{% endif %}
Filters

Default Fallback

Provides a fallback value if the variable is blank.

When to use:To prevent empty spaces if a merchant deletes the text in a setting.
{{ section.settings.title | default: 'Welcome to our store' }}
Filters

Handleize

Converts a string into a URL-safe handle (lowercase, spaces to dashes).

When to use:Generating clean HTML IDs from titles.
{{ 'Hello World' | handleize }}
<!-- Outputs: hello-world -->
Filters

Replace & Split

String manipulation filters.

When to use:When manipulating text data, or turning comma-separated settings into arrays.
{{ 'I like apples' | replace: 'apples', 'oranges' }}

{% assign words = 'one,two,three' | split: ',' %}
{{ words[1] }} <!-- Outputs: two -->
Filters

Money Filter

Formats integers (cents) into localized currency strings.

When to use:Every price on the storefront. Prices in Liquid are stored in cents.
Read related guide →
{{ product.price | money }}
{{ cart.total_price | money_with_currency }}
{{ 2500 | money_without_trailing_zeros }}
Filters

image_url Filter

Builds a CDN URL for an image at a specific width (WebP when supported).

When to use:Any image output. Pair with image_tag for full responsive markup.
Warning: img_url is deprecated—always use image_url instead.
{{ product.featured_image | image_url: width: 600 }}
{{ section.settings.banner | image_url: width: 2000, height: 800, crop: 'center' }}
Filters

Escape Filter

Escapes HTML in plain text so user input cannot break your layout.

When to use:All plain text settings, alt attributes, and SEO meta fields.
Read related guide →
<h1>{{ section.settings.title | escape }}</h1>
<meta name="description" content="{{ page_description | escape }}">
Filters

Append & Prepend

Adds characters to the start or end of a string.

When to use:Building titles, tel: links, or breadcrumb labels without extra assign tags.
{{ product.title | append: ' | ' | append: shop.name }}
{{ section.settings.phone | prepend: 'tel:' }}
Filters

Truncate Text

Shortens long strings for cards and previews.

When to use:Blog cards, collection descriptions, and mobile-friendly teasers.
{{ article.excerpt | truncate: 120 }}
{{ product.description | strip_html | truncatewords: 25 }}
Filters

Strip HTML

Removes HTML tags from rich text for plain previews.

When to use:Search results and meta descriptions—not for full article bodies.
{{ article.content | strip_html | truncate: 200 }}
Snippets

Render Snippet

Includes a reusable Liquid file from the /snippets folder.

When to use:For separating SVG icons or reusable components (like product cards) from massive section files.
{% render 'icon-cart' %}
Snippets

Passing Variables to Snippets

Send data into a snippet.

When to use:Snippets cannot access variables defined outside of them unless explicitly passed in.
{% render 'product-card', product: current_product, show_vendor: true %}
Snippets

Snippet with For Loop

Keeps heavy markup in snippets while the section owns the loop.

When to use:Product grids shared across collection pages, search, and recommendations.
{% for product in collection.products limit: 4 %}
  {% render 'product-card', product: product, lazy: true %}
{% endfor %}
Snippets

Capture Snippet Output

Stores rendered HTML in a variable for reuse.

When to use:When you need the same snippet output twice or must inject it into JSON-LD.
{% capture card_html %}
  {% render 'product-card', product: product %}
{% endcapture %}
{{ card_html }}
Performance

Section Rendering API

Fetch just the HTML of a section without reloading the page.

When to use:When building ajax cart drawers or quick-view modals to save bandwidth.
Read related guide →
fetch('/?section_id=cart-drawer')
  .then(response => response.text())
  .then(html => console.log(html));
Performance

Lazy Load Images

Defers loading images below the fold until they are near the viewport.

When to use:Product grids, blog lists, and footer logos. Do not lazy-load the LCP hero image.
Read related guide →
{{ product.featured_image | image_url: width: 800 | image_tag: loading: 'lazy', decoding: 'async' }}
Performance

Responsive image_tag

Lets Shopify generate srcset and sizes for you.

When to use:Product and collection images on responsive layouts.
{{ product.featured_image | image_url: width: 1200 | image_tag:
  loading: 'lazy',
  sizes: '(min-width: 990px) 50vw, 100vw',
  widths: '375, 550, 750, 1100, 1500'
}}
Performance

Avoid Nested Loops

Deep nesting can hit Shopify Liquid render limits and slow TTFB.

When to use:Refactor to fewer loops, use limit, or move heavy logic to the Section Rendering API / app blocks.
Warning: If a page times out in the theme editor, check for triple-nested loops first.
{% comment %} Bad: loop inside loop inside loop {% endcomment %}
{% for collection in collections %}
  {% for product in collection.products %}
    {% for tag in product.tags %}
      ...
    {% endfor %}
  {% endfor %}
{% endfor %}
Performance

Paginate Large Lists

Shopify caps unpaginated product loops at 50 items.

When to use:Collection pages, large blogs, and customer order history lists.
{% paginate collection.products by 24 %}
  {% for product in collection.products %}
    {% render 'product-card', product: product %}
  {% endfor %}
{% endpaginate %}
Performance

Defer Non-Critical Scripts

Loads JavaScript after HTML parsing when possible.

When to use:Theme-wide JS that is not required for first paint.
<script src="{{ 'theme.js' | asset_url }}" defer></script>
{% if template.name == 'product' %}
  <script src="{{ 'product-form.js' | asset_url }}" defer></script>
{% endif %}
Schema

Basic Section Schema

The minimum required JSON to make a section editable.

When to use:At the bottom of every new section file. Without 'presets', it cannot be added via the Theme Editor.
{% schema %}
{
  "name": "Custom Banner",
  "settings": [],
  "presets": [
    {
      "name": "Custom Banner"
    }
  ]
}
{% endschema %}
Schema

Block Schema Definition

How to define blocks inside a section schema.

When to use:When building sliders, galleries, or lists where merchants need to add multiple items.
Read related guide →
"blocks": [
  {
    "type": "slide",
    "name": "Slide",
    "settings": [
      {
        "type": "image_picker",
        "id": "image",
        "label": "Image"
      }
    ]
  }
]
Schema

Text Setting in Schema

The most common setting type for headings and labels.

When to use:Any short string merchants should edit—titles, eyebrow text, button labels.
{
  "type": "text",
  "id": "heading",
  "label": "Heading",
  "default": "Shop our bestsellers"
}
Schema

Richtext Schema Setting

Lets merchants use bold, links, and lists in the theme editor.

When to use:Longer copy areas where basic text is too limiting.
{
  "type": "richtext",
  "id": "body",
  "label": "Body copy",
  "default": "<p>Tell your brand story here.</p>"
}
Schema

Range Schema Setting

Numeric slider with min, max, step, and unit.

When to use:Spacing, opacity, column counts—anything merchants should tune visually.
{
  "type": "range",
  "id": "padding_top",
  "min": 0,
  "max": 100,
  "step": 4,
  "unit": "px",
  "label": "Top padding",
  "default": 36
}
Schema

Select Schema Setting

Dropdown that drives layout or style variants in Liquid.

When to use:When merchants pick between a small set of predefined layouts.
{
  "type": "select",
  "id": "layout",
  "label": "Layout",
  "options": [
    { "value": "grid", "label": "Grid" },
    { "value": "carousel", "label": "Carousel" }
  ],
  "default": "grid"
}
Schema

Checkbox Schema Setting

Boolean toggle stored as true or false.

When to use:Optional UI elements merchants can turn on or off.
{
  "type": "checkbox",
  "id": "show_rating",
  "label": "Show star rating",
  "default": true
}
Schema

Schema Presets with Blocks

Pre-populates blocks when a merchant adds the section.

When to use:Demos and client handoffs—merchants see working content immediately.
Read related guide →
"presets": [
  {
    "name": "FAQ",
    "blocks": [
      { "type": "question" },
      { "type": "question" }
    ]
  }
]
Schema

Limit Blocks (max_blocks)

Caps how many blocks merchants can add to a section.

When to use:Strict layouts (e.g. exactly 4 columns) or performance-sensitive sections.
{
  "name": "Logo list",
  "max_blocks": 8,
  "blocks": [
    { "type": "logo", "name": "Logo" }
  ]
}
Schema

Schema Header Divider

Groups settings in the sidebar for easier editing.

When to use:Sections with many settings—keeps the theme editor scannable.
{
  "type": "header",
  "content": "Colors"
},
{
  "type": "color",
  "id": "text_color",
  "label": "Text color",
  "default": "#111111"
}

Deep dive

Extended guide & workflows

How to use this reference on real theme work

Cheatsheets fail when they read like specification dumps. Treat this depth section as a field manual: look up the tag when you forget syntax, copy the pattern when you are mid-section, and return to /shopify-liquid-for-beginners when a concept—not a keyword—is what you are missing. Keep /converter open in another tab when you have HTML on the clipboard; generated output is often faster than handwriting boilerplate for image_tag chains and schema skeletons. Experienced Shopify developers still grep Dawn for filter usage because Shopify adds filters and objects over time—this page captures the stable ninety percent. When a client theme is three years old, watch for deprecated include tags and legacy asset filters; modern OS 2.0 work should align with render, image_url, and JSON templates exclusively.

Tag versus filter quick map

  {% ... %}  logic tags
      │          if / unless / case
      │          for / tablerow
      │          assign / capture
      │          render / liquid
      │
  {{ ... }}  output tags
      │          objects: product.title
      │          filters:  | money | image_url
      │
  {% schema %}  JSON (not Liquid logic)

Tags control flow and assignment; filters transform values inside output tags. Schema is JSON, not executable Liquid.

Money, units, and locale-aware formatting

money formats integers stored in cents—product.price is not a decimal dollar float. money_with_currency appends ISO code, useful in multi-currency contexts. money_without_trailing_zeros cleans whole-dollar displays. For compare-at pricing, output both prices inside a del wrapper for accessibility and theme CSS strikethrough rules. unit_price filters support measurement pricing when variant unit_price_measurement exists—niche but mandatory for certain CPG clients. Never manually divide by 100 unless you enjoy off-by-one rounding bugs. When building line item tables in cart snippets, line_item.final_line_price and line_item.original_line_price handle discounts better than recomputing from variant.price. For B2B or markets experiments, test money output on a store with active Shopify Markets; formatting changes with presentment currency.

Sale price row

{% if product.compare_at_price > product.price %}
  <s class="price price--compare">{{ product.compare_at_price | money }}</s>
{% endif %}
<span class="price price--current">{{ product.price | money }}</span>

Compare at greater than price is the standard on-sale test; style with CSS sibling selectors.

Image filters and responsive markup

image_url accepts width, height, crop, and format parameters—Shopify CDN handles resizing. Chain to image_tag for loading lazy, sizes, widths, and alt text. section.settings.image from image_picker is not a URL string; pipe it through image_url before img src. For srcset, pass widths as an array to image_tag when your theme version supports it; older patterns manually build srcset strings. focal_point settings on some themes crop from merchant-selected points—Dawn-derived themes increasingly expose this. placeholder_svg_tag renders gray placeholders in editor preview when images are blank—better than broken img icons during content entry. Always set alt from setting fields or product.title fallback; empty alt on decorative images should be intentional alt: '' not omitted attributes.

Arrays, where, map, and sort

where filters arrays of objects by property equality—handy for separating available variants without manual loops. map extracts a property list when you need handles or ids for data attributes. sort and reverse order collections for manual merchandising fallbacks when collection.sort_option is not enough. uniq removes duplicates after map. size or count counts items—know your theme's preference; both appear in the wild. first and last grab ends without indexing. combine joins arrays. These filters reduce Liquid loop noise but can hide performance costs if you chain them on large product sets inside nested loops. Prefer limiting collection.products before heavy filter chains. For metafield lists, check namespace and key access patterns in Shopify docs—list metafields iterate differently than single value strings.

  • split / join — break CSV metafields or build handle lists
  • replace / remove — sanitize merchant strings before class names
  • strip_html / escape — user-generated content in testimonials
  • default — fallback when settings or metafields are blank
  • append / prepend — build BEM modifiers without capture
  • date — format article and blog timestamps

Control flow beyond basic if and for

case block.type keeps multi-block sections readable compared to nested if elsif chains. unless inverts a condition—use sparingly when double negatives confuse readers. break and continue inside loops skip iterations when a guard trips—useful when filtering without where on older themes. cycle alternates CSS classes on zebra rows. tablerow renders HTML tables from arrays—rare in modern flex/grid themes but still appears in legacy email-style order summaries. liquid tag executes a string as Liquid—powerful and dangerous; avoid in merchant-editable settings unless you control the store completely. paginate wraps collection and search loops with paginate object—never forget to close paginate tags or pages silently fail. form tag generates cart, customer, and product forms with correct action endpoints—prefer it over hand-built forms that break CSRF expectations.

case on block.type with render

{% for block in section.blocks %}
  {% case block.type %}
    {% when 'heading' %}
      {% render 'block-heading', block: block %}
    {% when 'text' %}
      {% render 'block-text', block: block %}
  {% endcase %}
{% endfor %}

Pair case branches with focused snippets to keep section files under two hundred lines.

render parameters and snippet boundaries

render accepts only explicitly passed variables plus objects globally in scope per Shopify rules—do not rely on accidental parent leakage. Pass booleans for feature flags: show_vendor: section.settings.show_vendor. Pass string variants: size: 'small'. Inside snippets, use assign with default for optional parameters. render can target snippets in theme subfolders when organized—still one snippets directory in standard themes. for loops can wrap render to pass loop-specific context. Avoid rendering the same snippet fifty times with different heavy assigns outside the loop; assign shared data once before the loop. When debugging missing snippet errors, filename quotes are single-quoted without extension: {% render 'card-product' %}. Typos fail at render time with theme check errors—run CLI before push.

Schema patterns you paste weekly

Every section ends with presets—even a single preset with only a name. Blocks need type, name, and settings array even when empty. Range settings need min, max, step, and unit for editor UX. Select options are value and label pairs; values should be stable CSS tokens. color_scheme settings in Dawn tie into theme color groups defined in settings_schema.json—client child themes should extend the same groups rather than inventing hex pickers per section. header and paragraph types cost nothing and save training time. When copying schema between projects, audit ids for collisions with existing sections in the target theme—duplicate ids across different section files are fine; duplicates within one schema are not. Validate after merge; /liquid-schema-generator helps diff structural changes quickly.

Daily converter and QA workflow

  1. 01

    Paste HTML into /converter

    Strip analytics scripts and external fonts that belong in theme.liquid. Let the tool infer settings and blocks; note warnings about ambiguous repeatables.

  2. 02

    Compare output to cheatsheet patterns

    Verify image_tag chains, render usage, and blank guards match your team standards. Fix ids and add max_blocks before the first commit.

  3. 03

    Run theme check and preview in editor

    CLI theme check catches deprecated filters and missing templates. Editor preview confirms merchant UX—not just storefront HTML.

  4. 04

    Cross-link internal docs for the client

    Point content editors to /shopify-section-tutorial and this /shopify-cheat-sheet page for self-serve answers about blocks and settings.

  5. 05

    Archive the source HTML with the ticket

    Future you will need the original mockup when the client requests a fourth column variant six months later.

The cheatsheet is not a substitute for Shopify's official Liquid reference when you need every filter parameter—but official docs rarely tell you which patterns survive merchant editing for three years. Favor explicit blank checks, stable schema ids, render isolation, and CDN image filters over clever one-liners. When you outgrow copy-paste, read /shopify-schema-guide for editor UX and /dynamic-shopify-blocks-guide for slider and tab architectures. The goal is the same on every project: HTML becomes maintainable OS 2.0 sections, merchants stay independent, and the next developer on the repo does not reverse-engineer your intent from forty lines of nested Liquid.

Objects cheat sheet extension: search, blog, and pages

blog and article power content marketing templates—article.title, article.excerpt, article.image, article.url. blogs object lists all blogs when building hub pages. page object exists on page templates for corporate content. search object surfaces terms and results on search.json templates. linklists and linklists.main-menu access navigation menus configured in admin. canonical_url and page_title appear in SEO snippets. customer object is available when logged in—never cache PII in Liquid comments. localization object supports market selectors in global snippets. These objects are template-context sensitive like product—using article on index.json without a dedicated section assigning blog content yields nil. The request object exposes design_mode true in the editor, useful for loading developer-only assets without affecting live customers.

paginate and form tags in one glance

Wrap large collection and search loops in {% paginate collection.products by 24 %} ... {% endpaginate %} to access paginate.pages, paginate.current_page, and paginate.parts for numbered navigation. The by value should match your grid capacity times rows—twenty-four products is a common default for four-column grids. Inside paginate blocks, collection.products is already limited to the current page; do not add a conflicting limit on the inner for loop unless you intentionally show fewer than the page size. form tags generate correct action URLs and hidden fields for product, cart, customer, and localization forms—prefer {% form 'product', product %} over hand-built POST markup that breaks when Shopify updates checkout paths. After add-to-cart AJAX became common, many themes still keep canonical form tags for no-JS fallback and SEO crawlers.

Keeping the cheatsheet useful on long projects

Treat this reference as a living appendix to your theme repo, not a one-time read. Pin /shopify-cheat-sheet during development sprints and cross-link from internal PR templates: which filter chain you used for responsive images, which max_blocks cap you chose, which preset name merchants should search. When Shopify deprecates a filter or adds schema types, update your team snippets and verify converter warnings align. On multi-developer agencies, the cheatsheet reduces Slack questions about money versus money_with_currency or image_url width parameters. Pair it with /shopify-schema-guide when arguments are about editor UX, and with /shopify-section-tutorial when arguments are about JSON template registration. The interactive snippet browser above this deep dive is for fast copy-paste; the sections below are for judgment calls that snippets alone cannot answer.

Experienced developers still open the cheatsheet when switching between client themes because naming conventions differ even when Liquid syntax does not. Prestige may use different CSS variables than Dawn; the tags remain the same. Before you propose custom Liquid in a client call, confirm the pattern is not already a Shopify filter or a Dawn snippet you can reuse. That habit saves billable hours and reduces maintenance surface. When you mentor juniors, assign them to convert one Figma module with /converter, then map each generated line back to a cheatsheet entry—output tag, block loop, image filter. That exercise connects reference material to production code faster than reading documentation alone. This is how we train at K2 Devworks before anyone touches a production theme branch.

Bookmark the filter chains you use for product cards, collection grids, and article heroes—those three patterns cover most DTC homepage work. When a client requests Shopify Plus markets or B2B pricing, revisit official docs for object differences, then return here for syntax shape. The cheatsheet wins when your team shares the same defaults: lazy loading on below-fold images, money on prices, escape on user-supplied text, default on optional metafields. Consistency across sections matters more than micro-optimizing filter order on day one.

Need hands-on conversion? Open the free converter.

Editorial review

Reviewed by the HTML to Liquid Converter team

Dhruv Goyani, Shopify Developer at HTML to Liquid Converter

Dhruv Goyani

3 years web design + 3 years Shopify development experience

LinkedIn profile →
Nishad Kikani, Lead Shopify Developer at HTML to Liquid Converter

Nishad Kikani

2 years web design + 6 years Shopify development experience

LinkedIn profile →

Content is reviewed by the HTML to Liquid Converter Shopify development team before publication. Technical accuracy is validated against current Shopify Online Store 2.0 conventions and active client theme work.

Last updated:

Questions or corrections? Contact us.