What is Shopify Liquid? The template language behind your store, explained
Liquid is the language every Shopify theme is written in. You do not need to be a developer to understand how it works — and knowing the basics makes your theme much less mysterious.
Key takeaways
- Liquid is a template language: it fills an HTML page with your store's data before the page is sent to the shopper.
- It has three building blocks — objects in {{ }}, tags in {% %}, and filters after a | — and most theme code is just those three combined.
- Liquid runs on Shopify's servers, once per page request. It cannot react to clicks; that is JavaScript's job.
- Always edit a duplicate of your theme and preview before publishing.
Open any file in your Shopify theme's code editor and you will see HTML mixed with curly braces and percentage signs. That is Liquid, the template language Shopify created and every Shopify theme is written in. This guide explains what it is, how it works and what it can do, for store owners who want to understand their theme rather than become full-time developers.
What Liquid is
Liquid is a template language. A template is a page with gaps in it: the layout of a product page, say, with a gap where the product title goes, another for the price, another for the images. Liquid is the instructions that fill those gaps with real data. When someone visits a product, Shopify runs the template with that product's data and sends the finished HTML to their browser.
Shopify released Liquid as open source, and other tools use it too, but Shopify's version adds a large set of store-specific objects and filters: products, collections, carts, customers, money formatting, image resizing. When people say "Shopify Liquid", that is what they mean.
The three building blocks: objects, tags and filters
Objects: {{ }} prints something
Double curly braces output a value. {{ product.title }} prints the product's title. {{ shop.name }} prints your store's name. The word before the dot is an object (a bundle of data Shopify gives the page) and the word after it is a property of that object. Which objects exist depends on the page: product is there on a product page, collection on a collection page, while shop, cart and settings are available everywhere.
Tags: {% %} decides something
Curly brace and percent sign mark a tag: logic that does not print anything by itself. Tags make decisions (if, unless, case), repeat things (for), set variables (assign, capture) and pull in other files (render, section). A tag like {% if product.available %} lets the template show an "Add to cart" button only when the product can be bought.
Filters: | changes something
A filter comes after a pipe character and transforms a value before it is printed. {{ product.price | money }} turns a price stored in cents into your store's currency format. {{ product.title | upcase }} shows it in capitals. Filters can be chained, left to right: {{ product.featured_image | image_url: width: 800 | image_tag }} asks Shopify for an 800-pixel version of the image and builds the <img> tag for it.
A small annotated example
Here is a short piece of product-page Liquid using all three building blocks. Comments in Liquid are written with the comment tag, or with # inside {% liquid %} and inline tags, and they never reach the shopper.
{%- comment -%} Print the title, escaped so it can't break the HTML {%- endcomment -%}
<h1>{{ product.title | escape }}</h1>
{%- comment -%} Format the price in the store's currency {%- endcomment -%}
<p class="price">
{{ product.price | money }}
{%- if product.compare_at_price > product.price -%}
<s>{{ product.compare_at_price | money }}</s>
{%- endif -%}
</p>
{%- comment -%} Show a button only if the product can be bought {%- endcomment -%}
{%- if product.available -%}
<button type="submit" name="add">Add to cart</button>
{%- else -%}
<button type="button" disabled>Sold out</button>
{%- endif -%}
{%- comment -%} List every tag on the product {%- endcomment -%}
<ul>
{%- for tag in product.tags -%}
<li>{{ tag }}</li>
{%- endfor -%}
</ul>The hyphens in {%- and -%} strip the whitespace around a tag, which keeps the finished HTML tidy. They do not change what the code does.
Where Liquid runs
Liquid runs on Shopify's servers, once, when a page is requested. By the time the page reaches the browser, every {{ }} has been replaced by text and every {% %} has been resolved. If you view a page's source in your browser, you will not see any Liquid at all — only the HTML it produced.
That has one important consequence: Liquid cannot respond to what the shopper does. It cannot open an accordion when someone clicks, update a price when a variant is chosen, or count down a timer. Those are jobs for JavaScript, which runs in the browser after the page arrives. Most interactive theme features are Liquid that prints the content plus a small script that makes it move.
How a theme is organised: layouts, templates, sections, blocks and snippets
Online Store 2.0 themes split a page into layers. Knowing which is which tells you where to look when you want to change something.
| Part | Folder | What it is |
|---|---|---|
| Layout | layout/ | The outer frame of every page: theme.liquid holds the <head>, header and footer groups, and {{ content_for_layout }} where the page goes. |
| Template | templates/ | Which sections a page type shows, and in what order. In Online Store 2.0 these are usually JSON files. |
| Section | sections/ | A reusable, self-contained part of a page — a hero, a product grid, a FAQ — with its own settings. |
| Block | inside a section | A repeatable piece inside a section, like one slide or one FAQ question, that merchants can add, remove and reorder. |
| Snippet | snippets/ | A small piece of Liquid reused in many places, pulled in with {% render %}. |
| Settings | config/ | Theme-wide settings (colours, fonts) and their saved values. |
JSON templates and why sections matter
Before Online Store 2.0, most templates were Liquid files, and only the home page could be built from sections in the theme editor. Now templates are JSON files that list sections, so every page type can be assembled from sections and each section's settings are saved in that JSON. This is why a custom section is so useful: once a section file exists, you can add it to any page in the editor without touching code. Here is a cut-down JSON template:
{
"sections": {
"main": {
"type": "main-page",
"settings": {}
},
"faq": {
"type": "faq-accordion",
"settings": { "heading": "Questions, answered" }
}
},
"order": ["main", "faq"]
}Each entry's type is the name of a file in sections/. The section file itself ends with a {% schema %} tag: JSON that declares the section's name, its settings, its blocks and its presets. Without presets, a section will not appear in the theme editor's "Add section" list — a common reason a custom section is not showing in the theme editor. The section schema generator can build and check a schema for you.
<div class="announcement" style="background: {{ section.settings.background }}">
<p>{{ section.settings.text }}</p>
</div>
{% schema %}
{
"name": "Announcement",
"settings": [
{ "type": "text", "id": "text", "label": "Text", "default": "Free delivery over 50" },
{ "type": "color", "id": "background", "label": "Background", "default": "#111111" }
],
"presets": [{ "name": "Announcement" }]
}
{% endschema %}Notice section.settings.text: the section reads its own settings, and the merchant changes them in the theme editor. Turning hard-coded words, colours and images into settings is what makes a section editable — see how to make a Shopify section editable.
What you can and cannot do with Liquid
You can display almost anything about your store: products, variants, collections, blog posts, pages, metafields and metaobjects, the cart, the logged-in customer, translations. You can show and hide things based on conditions, loop through lists, resize images, format money and dates, and build forms for the cart, contact and newsletter.
You cannot save data, call an outside API, run on a schedule, change a price at checkout, or react to clicks. Liquid reads and displays; it does not write. Those jobs belong to JavaScript in the browser, Shopify Functions, or an app. If you are weighing that choice, Shopify app vs custom section goes through it.
How to edit Liquid safely
Duplicate your live theme
In Online Store → Themes, open the live theme's menu and choose Duplicate. Make every change on the copy.
Open the code editor
On the duplicate, choose Edit code. Find the file you want in
sections,snippetsortemplates.Make one change at a time
Save, then preview. If something breaks, the editor's version history lets you go back to an earlier version of the file.
Preview on real pages
Check desktop and mobile, a product with and without a sale price, an empty cart. Liquid errors usually show on the page as a message, not a crash.
Publish when it works
Publish the duplicate. Keep the old theme for a while in case you need to compare.
Where to learn more
Shopify's own Liquid reference is the authority. It lists every object with its properties, every tag and every filter, each with examples, and it is kept up to date as Shopify adds features. Use it to look up exactly what product or image_url gives you. Shopify's theme documentation on shopify.dev explains the theme architecture, section schemas and blocks in depth.
If you would rather describe what you want than write it, the Shopify Liquid code generator writes a complete section — markup, CSS, JavaScript and schema with settings, blocks and presets — from a plain-English description. Reading the code it produces is also a good way to learn: you can see each building block from this guide in a real section. How to add a custom section to Shopify shows where to put it.
Questions, answered
What is Liquid in Shopify?
Liquid is the template language Shopify themes are written in. It fills HTML pages with your store's data, such as product titles, prices and images, on Shopify's servers before the page is sent to the shopper's browser.
Is Shopify Liquid hard to learn?
The basics are approachable: objects in {{ }} print data, tags in {% %} add logic, and filters after a | format values. Reading and making small edits takes a few hours to learn. Building full sections well also needs HTML, CSS and some JavaScript.
Is Liquid the same as JavaScript?
No. Liquid runs on Shopify's servers once per page request and produces HTML. JavaScript runs in the shopper's browser and handles interaction such as clicks, sliders and variant changes. Most themes use both.
What is the difference between a Shopify section and a snippet?
A section is a self-contained part of a page with its own schema and settings that merchants can add and edit in the theme editor. A snippet is a reusable piece of Liquid pulled in with the render tag; it has no schema and does not appear in the editor.
Where do I edit Liquid code in Shopify?
In the Shopify admin, go to Online Store, then Themes, open a theme's menu and choose Edit code. Duplicate the theme first and make changes on the copy, then preview before publishing.