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
Render Section Setting
Outputs a text or basic setting value from the section schema.
{{ section.settings.title }}Render Image (Modern)
The modern, performant way to render an image picker setting with automatic WebP support.
{{ section.settings.image | image_url: width: 800 | image_tag: loading: 'lazy', class: 'my-custom-class' }}Basic For Loop
Loops through section blocks to render repeated content like a gallery or FAQ.
{% for block in section.blocks %}
<div {{ block.shopify_attributes }}>
{{ block.settings.heading }}
</div>
{% endfor %}All snippets
Render Section Setting
Outputs a text or basic setting value from the section schema.
{{ section.settings.title }}Render Image (Modern)
The modern, performant way to render an image picker setting with automatic WebP support.
{{ section.settings.image | image_url: width: 800 | image_tag: loading: 'lazy', class: 'my-custom-class' }}Basic For Loop
Loops through section blocks to render repeated content like a gallery or FAQ.
{% for block in section.blocks %}
<div {{ block.shopify_attributes }}>
{{ block.settings.heading }}
</div>
{% endfor %}Product Title
Outputs the title of the current product.
{{ product.title }}Product Price Formatting
Formats the product price according to the store's currency settings.
{{ product.price | money }}
<!-- Compare at price -->
{{ product.compare_at_price | money }}Product Vendor & Type
Outputs the vendor (brand) and product type.
{{ product.vendor }}
{{ product.type }}Product Tags Loop
Iterates through all tags attached to a product.
{% for tag in product.tags %}
<span class="badge">{{ tag }}</span>
{% endfor %}First Available Variant
Gets the first variant that is currently in stock.
{% assign current_variant = product.selected_or_first_available_variant %}
{{ current_variant.price | money }}Product Media Gallery
Loops through all images, videos, and 3D models attached to a product.
{% for media in product.media %}
{% render 'media', media: media %}
{% endfor %}Product Description
Outputs the main product description HTML from the admin.
<div class="product-description rte">
{{ product.description }}
</div>Product Description (Plain Preview)
Strips HTML tags for short previews in cards or search results.
{{ product.description | strip_html | truncate: 120 }}Product URL
The canonical URL path for the current product.
<a href="{{ product.url }}">{{ product.title }}</a>Check Product Availability
Returns true if at least one variant can be purchased.
{% if product.available %}
<button type="submit" name="add">Add to cart</button>
{% else %}
<button disabled>Sold out</button>
{% endif %}Featured Product Image
Renders the product's main image using modern Shopify image filters.
{% if product.featured_image %}
{{ product.featured_image | image_url: width: 1200 | image_tag: loading: 'eager', alt: product.featured_image.alt | escape }}
{% endif %}Featured Media (OS 2.0)
Accesses the primary media object, which may be an image, video, or 3D model.
{% if product.featured_media %}
{% render 'product-media', media: product.featured_media %}
{% endif %}Loop All Variants
Iterates every variant (size, color, etc.) on a product.
{% for variant in product.variants %}
<option value="{{ variant.id }}" {% unless variant.available %}disabled{% endunless %}>
{{ variant.title }} — {{ variant.price | money }}
</option>
{% endfor %}Variant SKU & Barcode
Outputs inventory identifiers for the selected or first available variant.
{% assign v = product.selected_or_first_available_variant %}
<p>SKU: {{ v.sku }}</p>
<p>Barcode: {{ v.barcode }}</p>Product Options (Size, Color)
Loops option names and values—for example Color: Red, Blue.
{% 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 %}Check for Specific Tag
Shows content only when a product has a given tag.
{% if product.tags contains 'sale' %}
<span class="badge badge--sale">On sale</span>
{% endif %}Collection Title & Description
Outputs the collection's title and its rich text description.
<h1>{{ collection.title }}</h1>
<div>{{ collection.description }}</div>Loop Collection Products
Iterates through products in a specific collection.
{% for product in collection.products %}
<h2>{{ product.title }}</h2>
{% else %}
<p>No products found.</p>
{% endfor %}Paginate Collection
Required for collections with more than 50 products.
{% paginate collection.products by 12 %}
{% for product in collection.products %}
<!-- Render product card -->
{% endfor %}
{{ paginate | default_pagination }}
{% endpaginate %}Collection URL & Handle
Builds links and CSS hooks from the collection object.
<a href="{{ collection.url }}">{{ collection.title }}</a>
<!-- Handle for data attributes -->
data-collection="{{ collection.handle }}"Collection Product Count
Shows how many products belong to the collection.
<p>{{ collection.products_count }} products</p>Collection Featured Image
Renders the image uploaded for the collection in the admin.
{% if collection.image %}
{{ collection.image | image_url: width: 1600 | image_tag: loading: 'lazy', alt: collection.title | escape }}
{% endif %}Collection from Section Setting
Loops products from a collection the merchant picked in the theme editor.
{% assign featured = section.settings.collection %}
{% if featured != blank %}
{% for product in featured.products limit: section.settings.limit %}
{% render 'product-card', product: product %}
{% endfor %}
{% endif %}Paginate Blog Articles
Pagination works for blogs too—not only collections.
{% 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 Item Count & Total
Displays the total number of items and the total price of the cart.
{{ cart.item_count }} items
{{ cart.total_price | money_with_currency }}Cart Items Loop
Loops through all items currently in the cart.
{% 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 %}Empty Cart Check
Shows different markup when the cart has zero items.
{% 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 Subtotal vs Total
Displays line totals; cart.total_price includes discounts where applicable.
<p>Subtotal: {{ cart.total_price | money }}</p>
<p>Items: {{ cart.item_count }}</p>Line Item Variant Title
Shows the variant name (e.g. Size M / Color Black) for each cart line.
{% for item in cart.items %}
<p class="line-item__variant">{{ item.variant.title }}</p>
{% endfor %}Line Item Properties
Outputs custom properties added at add-to-cart (engraving, gift message, etc.).
{% 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 Note Field
Outputs the optional note customers leave for the store.
<textarea name="note">{{ cart.note }}</textarea>Check if Logged In
Checks if a customer is currently logged into their account.
{% 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 Full Name
Outputs first and last name, or a combined name when available.
{{ customer.name }}
<!-- Or separately -->
{{ customer.first_name }} {{ customer.last_name }}Customer Account Links
Uses Shopify route objects for correct login, register, and logout URLs.
<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 Email & Orders
Shows account email and loops recent orders on the account page.
<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 %}Default Customer Address
Outputs the customer's default shipping address when set.
{% 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 Articles Loop
Loops through articles in a specific blog (e.g., 'news').
{% 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 %}Article Title & URL
Standard article heading and permalink on article templates.
<h1>{{ article.title }}</h1>
<p><time datetime="{{ article.published_at | date: '%Y-%m-%d' }}">{{ article.published_at | date: format: 'abbreviated_date' }}</time></p>Article Content
Outputs the full article body HTML from the blog editor.
<div class="article-content rte">
{{ article.content }}
</div>Article Author & Image
Shows byline and featured image when present.
{% if article.image %}
{{ article.image | image_url: width: 1200 | image_tag: loading: 'lazy', alt: article.title | escape }}
{% endif %}
<p>By {{ article.author }}</p>Current Blog Title
Outputs the name of the blog handle you are viewing (News, Journal, etc.).
<h1>{{ blog.title }}</h1>
<p>{{ blog.articles_count }} articles</p>Loop Articles on Blog Template
Standard loop when you are already on a blog listing template.
{% 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 %}Global Theme Settings
Access settings defined in settings_schema.json (globally available).
{{ settings.color_primary }}
{{ settings.social_instagram_link }}Richtext Output
Outputs a richtext schema setting properly.
<div class="rte">
{{ section.settings.text }}
</div>Select Setting Condition
Using a dropdown select setting to change layout logic.
{% if section.settings.alignment == 'center' %}
<div class="text-center">
{% else %}
<div class="text-left">
{% endif %}Block Settings
Reads values from an individual block inside a section loop.
{% for block in section.blocks %}
<div {{ block.shopify_attributes }}>
<h3>{{ block.settings.heading }}</h3>
<p>{{ block.settings.text }}</p>
</div>
{% endfor %}Image Picker Setting
Outputs an image from a section or block image_picker field.
{% if section.settings.image != blank %}
{{ section.settings.image | image_url: width: 800 | image_tag: loading: 'lazy', alt: section.settings.image.alt | escape }}
{% endif %}Range Setting (Spacing)
Uses a numeric range value from schema—often for padding or font size.
<div style="padding-top: {{ section.settings.padding }}px;">
<!-- content -->
</div>Checkbox Toggle
Shows or hides elements based on a true/false schema checkbox.
{% if section.settings.show_vendor %}
<p class="product-card__vendor">{{ product.vendor }}</p>
{% endif %}Color Setting
Applies a merchant-selected color from the theme editor.
<div style="background-color: {{ section.settings.bg_color }};">
{{ section.settings.heading }}
</div>URL Setting Link
Builds a CTA from a url-type schema setting.
{% if section.settings.button_link != blank %}
<a href="{{ section.settings.button_link }}" class="btn">
{{ section.settings.button_label | escape }}
</a>
{% endif %}Product Metafield
Outputs a custom metafield attached to a product.
{{ product.metafields.custom.care_instructions }}Render Rich Text Metafield
Safely renders HTML from a Rich Text Metafield.
{{ product.metafields.custom.details | metafield_tag }}Check Metafield Before Output
Avoids empty wrappers when a metafield has no value.
{% if product.metafields.custom.size_chart != blank %}
<div class="size-chart">
{{ product.metafields.custom.size_chart | metafield_tag }}
</div>
{% endif %}Collection Metafield
Outputs custom data attached to a collection.
{{ collection.metafields.custom.seo_intro }}Article Metafield
Displays custom fields on blog posts—reading time, series, etc.
{% if article.metafields.custom.reading_time != blank %}
<span>{{ article.metafields.custom.reading_time }} min read</span>
{% endif %}Shop-Level Metafield
Reads metafields on the shop object for global theme data.
{{ shop.metafields.custom.announcement_text }}For Loop with Limit
Loops exactly X number of times.
{% for product in collection.products limit: 4 %}
{{ product.title }}
{% endfor %}Forloop Object (Index)
Access the current iteration number of a loop.
{% 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 %}Loop with Offset
Skips the first N items—handy when the first product is featured elsewhere.
{% for product in collection.products limit: 4 offset: 1 %}
{% render 'product-card', product: product %}
{% endfor %}Reversed Loop
Iterates from last to first without mutating the original array.
{% for block in section.blocks reversed %}
{{ block.settings.heading }}
{% endfor %}Assign Before Loop
Stores a collection or product in a variable for cleaner templates.
{% assign featured_products = section.settings.collection.products %}
{% for product in featured_products limit: 8 %}
{{ product.title }}
{% endfor %}Tablerow for Grid Layouts
Opens and closes HTML rows every N columns automatically.
<table>
{% tablerow product in collection.products cols: 3 %}
<td>{{ product.title }}</td>
{% endtablerow %}
</table>If / Elsif / Else
Standard conditional logic.
{% if product.price < 5000 %}
Budget Friendly
{% elsif product.price < 10000 %}
Mid-Range
{% else %}
Premium
{% endif %}Unless (If Not)
The opposite of 'if'. Executes if the condition is false.
{% unless product.available %}
Sold Out!
{% endunless %}Case / When
A switch statement for cleaner multiple-condition checks.
{% 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 %}Check if Blank
Liquid treats empty strings, false, and nil as falsy in conditionals.
{% if section.settings.heading != blank %}
<h2>{{ section.settings.heading | escape }}</h2>
{% endif %}Contains Operator
Checks whether a string or array includes a value.
{% if product.tags contains 'featured' %}
<span class="badge">Featured</span>
{% endif %}
{% if cart.attributes['gift'] == 'yes' %}
<!-- gift wrap UI -->
{% endif %}Default Fallback
Provides a fallback value if the variable is blank.
{{ section.settings.title | default: 'Welcome to our store' }}Handleize
Converts a string into a URL-safe handle (lowercase, spaces to dashes).
{{ 'Hello World' | handleize }}
<!-- Outputs: hello-world -->Replace & Split
String manipulation filters.
{{ 'I like apples' | replace: 'apples', 'oranges' }}
{% assign words = 'one,two,three' | split: ',' %}
{{ words[1] }} <!-- Outputs: two -->Money Filter
Formats integers (cents) into localized currency strings.
{{ product.price | money }}
{{ cart.total_price | money_with_currency }}
{{ 2500 | money_without_trailing_zeros }}image_url Filter
Builds a CDN URL for an image at a specific width (WebP when supported).
{{ product.featured_image | image_url: width: 600 }}
{{ section.settings.banner | image_url: width: 2000, height: 800, crop: 'center' }}Escape Filter
Escapes HTML in plain text so user input cannot break your layout.
<h1>{{ section.settings.title | escape }}</h1>
<meta name="description" content="{{ page_description | escape }}">Append & Prepend
Adds characters to the start or end of a string.
{{ product.title | append: ' | ' | append: shop.name }}
{{ section.settings.phone | prepend: 'tel:' }}Truncate Text
Shortens long strings for cards and previews.
{{ article.excerpt | truncate: 120 }}
{{ product.description | strip_html | truncatewords: 25 }}Strip HTML
Removes HTML tags from rich text for plain previews.
{{ article.content | strip_html | truncate: 200 }}Render Snippet
Includes a reusable Liquid file from the /snippets folder.
{% render 'icon-cart' %}Passing Variables to Snippets
Send data into a snippet.
{% render 'product-card', product: current_product, show_vendor: true %}Snippet with For Loop
Keeps heavy markup in snippets while the section owns the loop.
{% for product in collection.products limit: 4 %}
{% render 'product-card', product: product, lazy: true %}
{% endfor %}Capture Snippet Output
Stores rendered HTML in a variable for reuse.
{% capture card_html %}
{% render 'product-card', product: product %}
{% endcapture %}
{{ card_html }}Section Rendering API
Fetch just the HTML of a section without reloading the page.
fetch('/?section_id=cart-drawer')
.then(response => response.text())
.then(html => console.log(html));Lazy Load Images
Defers loading images below the fold until they are near the viewport.
{{ product.featured_image | image_url: width: 800 | image_tag: loading: 'lazy', decoding: 'async' }}Responsive image_tag
Lets Shopify generate srcset and sizes for you.
{{ product.featured_image | image_url: width: 1200 | image_tag:
loading: 'lazy',
sizes: '(min-width: 990px) 50vw, 100vw',
widths: '375, 550, 750, 1100, 1500'
}}Avoid Nested Loops
Deep nesting can hit Shopify Liquid render limits and slow TTFB.
{% 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 %}Paginate Large Lists
Shopify caps unpaginated product loops at 50 items.
{% paginate collection.products by 24 %}
{% for product in collection.products %}
{% render 'product-card', product: product %}
{% endfor %}
{% endpaginate %}Defer Non-Critical Scripts
Loads JavaScript after HTML parsing when possible.
<script src="{{ 'theme.js' | asset_url }}" defer></script>
{% if template.name == 'product' %}
<script src="{{ 'product-form.js' | asset_url }}" defer></script>
{% endif %}Basic Section Schema
The minimum required JSON to make a section editable.
{% schema %}
{
"name": "Custom Banner",
"settings": [],
"presets": [
{
"name": "Custom Banner"
}
]
}
{% endschema %}Block Schema Definition
How to define blocks inside a section schema.
"blocks": [
{
"type": "slide",
"name": "Slide",
"settings": [
{
"type": "image_picker",
"id": "image",
"label": "Image"
}
]
}
]Text Setting in Schema
The most common setting type for headings and labels.
{
"type": "text",
"id": "heading",
"label": "Heading",
"default": "Shop our bestsellers"
}Richtext Schema Setting
Lets merchants use bold, links, and lists in the theme editor.
{
"type": "richtext",
"id": "body",
"label": "Body copy",
"default": "<p>Tell your brand story here.</p>"
}Range Schema Setting
Numeric slider with min, max, step, and unit.
{
"type": "range",
"id": "padding_top",
"min": 0,
"max": 100,
"step": 4,
"unit": "px",
"label": "Top padding",
"default": 36
}Select Schema Setting
Dropdown that drives layout or style variants in Liquid.
{
"type": "select",
"id": "layout",
"label": "Layout",
"options": [
{ "value": "grid", "label": "Grid" },
{ "value": "carousel", "label": "Carousel" }
],
"default": "grid"
}Checkbox Schema Setting
Boolean toggle stored as true or false.
{
"type": "checkbox",
"id": "show_rating",
"label": "Show star rating",
"default": true
}Schema Presets with Blocks
Pre-populates blocks when a merchant adds the section.
"presets": [
{
"name": "FAQ",
"blocks": [
{ "type": "question" },
{ "type": "question" }
]
}
]Limit Blocks (max_blocks)
Caps how many blocks merchants can add to a section.
{
"name": "Logo list",
"max_blocks": 8,
"blocks": [
{ "type": "logo", "name": "Logo" }
]
}Schema Header Divider
Groups settings in the sidebar for easier editing.
{
"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
- 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.
- 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.
- 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.
- 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.
- 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


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.