Skip to content

Liquid Templating Language

Liquid is Shopify’s templating language. It lives inside your theme files and does one job: it pulls data from your store and outputs it as HTML for the browser to display.

When a customer visits a product page, Shopify doesn’t serve a static file. It takes the Liquid template for product pages, fills in the relevant data (title, price, images, variants) and generates the HTML on the fly. This happens on every page load.

Liquid has three main building blocks:


Objects are wrapped in double curly braces {{ }} and output values from your store.

Given: product.title = 'Chore Jacket', product.price = 8500, shop.name = 'Haneru Supply'

Liquid
{{ product.title }}
{{ product.price | money }}
{{ shop.name }}
Rendered

Chore Jacket

£85.00

Haneru Supply

These pull data directly from Shopify: the product title, its formatted price, your store name. You’ll see these throughout any theme file.


Tags are wrapped in curly braces with percent signs {% %} and handle logic: conditionals, loops, and layout structure.

Given: product.available = true

Liquid
{% if product.available %}
<button>Add to cart</button>
{% else %}
<p>Out of stock</p>
{% endif %}
Rendered

If product.available were false, the same snippet would render as Out of stock instead. The logic runs at render time, so each visitor gets the right state.

Given: product.variants = [Small, Medium, Large]

Liquid
<select>
{% for variant in product.variants %}
<option value="{{ variant.id }}">{{ variant.title }}</option>
{% endfor %}
</select>
Rendered

The for loop iterates over every variant on the product and outputs an <option> for each one, producing a working dropdown without the theme author ever having to hard-code the variants.


Filters modify what an object outputs. They’re added after a pipe character |.

Given: product.price = 8500, product.title = 'Chore Jacket', article.published_at = 2026-04-15

Liquid
{{ product.price | money }}
{{ product.title | upcase }}
{{ article.published_at | date: "%B %d, %Y" }}
Rendered

£85.00

CHORE JACKET

April 15, 2026

money formats a price with the correct currency symbol and decimal places, upcase converts text to uppercase, and date turns a raw timestamp into a readable format. Filters can also be chained — {{ product.title | upcase | truncate: 20 }} would uppercase the title and then trim it to 20 characters.


Here’s a real-world example, a snippet you might find in a product card template. It combines all three building blocks: objects pull the data, a filter formats the image URL and price, and a tag conditionally shows a sale badge.

Given: product = Chore Jacket at £85.00 (compare_at_price = £120.00)

Liquid
<div class="product-card">
<a href="{{ product.url }}">
<img src="{{ product.featured_image | img_url: '400x' }}" alt="{{ product.title }}">
<h2>{{ product.title }}</h2>
<p>{{ product.price | money }}</p>
{% if product.compare_at_price > product.price %}
<span class="sale-badge">Sale</span>
{% endif %}
</a>
</div>
Rendered

Product image

Chore Jacket

£85.00

Sale
Same snippet, different products — the badge only appears when there's a real discount.

No hardcoded values anywhere; everything is pulled from Shopify at render time. One template, one file — and every product on the store renders through it.


Understanding Liquid at this level means you can open a theme file and follow what it’s doing — which is a meaningful step. From here:

  • Browse Dawn’s templates in Online Store → Themes → Edit code to see real Liquid in context
  • Shopify’s Liquid reference documentation covers every available object, tag, and filter in full detail