Shopify themes are built on Liquid, a templating language that controls everything from how a product title displays to whether a sale badge appears on a product card.
You do not need to master Liquid to run a Shopify store. But if you want to make meaningful customisations beyond what the theme editor allows, understanding Liquid is essential.
This Shopify Liquid tutorial covers the core concepts you need: objects, tags, filters, and the file structure of a Shopify theme. By the end, you will be able to make targeted edits confidently and safely without risking your live store.
Before You Touch Any Code: Set Up a Safe Environment
Making changes directly to a live Shopify theme without a backup is the fastest way to break your store for real customers. Always follow this three-step safety process before editing any Liquid file.
Step 1: Duplicate your theme
Go to Online Store > Themes > click the three-dot menu on your active theme > Duplicate. This creates a backup you can restore instantly if anything goes wrong.
Step 2: Use a development store or theme preview
Make changes on your duplicated theme and use the preview function to test before publishing. For more complex changes, use a free Shopify development store through a Partner account.
Step 3: Make one change at a time
Never edit multiple files in a single session without testing between changes. If something breaks, you need to know exactly which edit caused it.
Our guide on Shopify theme version control covers how to manage theme edits safely at every level, from simple text changes to full section rebuilds.
How to Access the Liquid Code Editor
Go to Shopify Admin > Online Store > Themes. Click the three-dot menu on your active theme and select “Edit code.”
The code editor shows your full theme file structure in the left panel:
| Folder | What It Contains |
|---|---|
| Layout | Master page templates (theme.liquid is the global wrapper) |
| Templates | Page-type templates (product, collection, index, etc.) |
| Sections | Reusable, editor-configurable page components |
| Snippets | Reusable code fragments included in other files |
| Assets | CSS, JavaScript, and image files |
| Config | Theme settings and translation files |
| Locales | Language translation JSON files |
Start by understanding theme.liquid in the Layout folder. It is the global wrapper for every page on your store. Every template file renders inside the {{ content_for_layout }} tag in theme.liquid.
Liquid Syntax: The Three Building Blocks
Liquid has three core syntax types. Every customisation you make uses some combination of these.
1. Objects: Output Data with Double Curly Braces
Objects output store data as text in your template.
{{ product.title }} {{ product.price | money }} {{ shop.name }} {{ collection.description }}
Anything inside {{ }} is an object or variable output. Shopify provides hundreds of built-in objects including product, collection, cart, customer, shop, and page.
2. Tags: Control Logic with Curly Brace Percent Signs
Tags control flow and logic. They do not output text themselves.
{% if product.available %}
<button>Add to Cart</button>
{% else %}
<p>Sold Out</p>
{% endif %}
{% for product in collection.products %}
<div>{{ product.title }}</div>
{% endfor %}
The most common tags you will use are if, elsif, else, endif, for, endfor, unless, assign, capture, render, and include.
3. Filters: Transform Output with Pipes
Filters modify the output of an object. They are placed after a pipe character inside output tags.
{{ product.title | upcase }} {{ product.price | money }} {{ product.description | truncate: 100 }} {{ 'styles.css' | asset_url | stylesheet_tag }} {{ product.featured_image | image_url: width: 600 | image_tag }}
Common Shopify-specific filters:
| Filter | What It Does |
|---|---|
money |
Formats a price using the store’s currency settings |
image_url: width: N |
Returns a CDN URL for a resized image |
image_tag |
Renders a full <img> tag from a URL |
asset_url |
Returns the CDN URL of a theme asset file |
stylesheet_tag |
Wraps a URL in a <link> stylesheet tag |
script_tag |
Wraps a URL in a <script> tag |
truncate: N |
Cuts text to N characters |
strip_html |
Removes HTML tags from a string |
escape |
Escapes HTML special characters for safe output |
default: 'value' |
Returns a fallback if the variable is blank |
url_encode |
Encodes a string for use in a URL |
Understanding Shopify Liquid Objects
The most important objects to learn when you learn shopify liquid are the ones you will use on every template.
Product Object
{{ product.title }} {{ product.price | money }} {{ product.vendor }} {{ product.type }} {{ product.description }} {{ product.url }} {{ product.featured_image | image_url: width: 800 | image_tag }} {{ product.available }} {# Returns true or false #}
Collection Object
{{ collection.title }} {{ collection.description }} {% for product in collection.products %} {{ product.title }} {% endfor %}
Cart Object
{{ cart.item_count }} {{ cart.total_price | money }} {% for item in cart.items %} {{ item.product.title }} x {{ item.quantity }} {% endfor %}
Customer Object
{% if customer %} Hello, {{ customer.first_name }} {% else %} <a href="/account/login">Log in</a> {% endif %}
Practical Example 1: Add a Sale Badge to Product Cards
This is one of the most common shopify theme customization liquid tasks. You want a “Sale” badge to appear on product cards when a product has a compare-at price higher than its current price.
Find your product card snippet, typically named product-card.liquid or card-product.liquid in the Snippets folder. Add this code where the badge should appear:
{% if product.compare_at_price > product.price %} <span class="badge badge--sale">Sale</span> {% endif %}
Add CSS to your theme’s stylesheet to style the badge:
.badge--sale { background-color: #e53e3e; color: white; padding: 4px 8px; font-size: 12px; font-weight: bold; border-radius: 4px; }
Practical Example 2: Show a Custom Message for Out-of-Stock Products
Find your product template, typically product.liquid or main-product.liquid in the Sections folder. Locate the add-to-cart button area and add conditional logic:
{% if product.available %} <button type="submit" name="add" class="btn btn--primary"> Add to Cart </button> {% else %} <button type="button" class="btn btn--disabled" disabled> Sold Out </button> <p class="sold-out-message"> Join our waitlist to be notified when this item is back in stock. </p> {% endif %}
Practical Example 3: Display Metafields in a Template
Metafields store custom data for products, collections, and other resources. Once defined, you can output them in any Liquid template.
{% if product.metafields.custom.care_instructions != blank %} <div class="care-instructions"> <h3>Care Instructions</h3> <p>{{ product.metafields.custom.care_instructions }}</p> </div> {% endif %}
Our Shopify metafields guide covers how to define, manage, and output metafields across every Shopify resource type.
The render Tag vs the include Tag
Older Shopify themes used
{% include 'snippet-name' %}
to pull in snippet files. This is deprecated.
The modern approach uses
{% render 'snippet-name' %}:
{% render 'product-card', product: product %}
The key difference is that render creates an isolated scope. Variables defined outside a render tag are not automatically available inside it. You must explicitly pass data to the snippet:
{% render 'icon-star', filled: true, size: 16 %}
Always use render instead of include in any new Liquid code you write. The include tag is slower, harder to debug, and no longer recommended by Shopify.
The assign and capture Tags
Use assign to create a variable and capture to store a block of output as a variable.
{% assign sale_threshold = 0.8 %}
{% if product.price < product.compare_at_price | times: sale_threshold %}
On Sale
{% endif %}
{% capture product_badge %}
{% if product.available == false %}
<span>Sold Out</span>
{% elsif product.compare_at_price > product.price %}
<span>Sale</span>
{% endif %}
{% endcapture %}
{{ product_badge }}
The capture tag is useful for building complex strings or HTML blocks that depend on conditional logic before outputting them in a single location.
Performance Rules for Liquid Code
Bad Liquid code does not just look ugly. It slows down your store. Every unnecessary loop, redundant object call, and unoptimised image output adds to your server render time.
| Bad Practice | Better Approach |
|---|---|
{% for product in collections.all.products %} |
Paginate or limit with limit parameter |
Accessing all_products global object |
Use collection-scoped product loops |
| Loading full product images without width | Always use image_url: width: N |
Using include instead of render |
Always use render |
| Nesting loops inside loops | Flatten data access patterns where possible |
No {% unless %} for negative conditions |
Use unless instead of {% if x == false %} |
Our guide on Shopify Liquid optimisation covers advanced performance techniques for reducing render time in complex Liquid templates. For understanding how Liquid render performance connects to your search rankings, see our Shopify Core Web Vitals guide.
Common Liquid Mistakes That Break Themes
These errors cause the most problems for developers new to shopify liquid code guide work:
- Forgetting to close tags. Every
{% if %}needs{% endif %}. Every{% for %}needs{% endfor %}. Missing closing tags cause entire sections of a page to disappear or render incorrectly. - Accessing unavailable objects on the wrong template. The
productobject is only available on product templates. Using{{ product.title }}on a collection template returns blank. - Using
includeinstead ofrender. Theincludetag is deprecated and introduces scope pollution bugs in complex themes. - Modifying theme.liquid without testing. This file wraps every page. An error here breaks the entire store.
- Using
collections.allin a loop without limits. This can return thousands of products and cause timeout errors on large stores.
For a broader look at technical errors that affect store performance and customer experience, our post on Shopify technical mistakes covers the patterns that cause the most ongoing problems.
Liquid in Context: Sections, Snippets, and Templates
Understanding when to use each file type makes your Liquid work more maintainable.
| File Type | When to Use It |
|---|---|
| Section file | For page components that merchants edit through the theme editor |
| Snippet file | For reusable code fragments used across multiple templates |
| Template file | For page-type-specific layouts (product, collection, blog, etc.) |
| Layout file | For global structure that wraps all pages (header, footer, scripts) |
Our guide on how to build custom Shopify sections covers the specific Liquid and JSON schema structure required for sections in detail, including blocks and merchant-editable settings.
Combining section development with a solid understanding of Liquid syntax gives you the ability to build custom storefronts that are both functionally rich and fully editable by non-technical team members.
Should You Learn Liquid or Go Headless?
Liquid is the right foundation for the vast majority of Shopify customisation work. It is fast, well-documented, and deeply integrated with every Shopify feature.
Headless architectures using Shopify Hydrogen replace Liquid with React components and the Storefront API. This opens up more complex UI patterns but removes the theme editor entirely.
If you are trying to decide between the two approaches, our comparison of Shopify Hydrogen vs Liquid provides a clear framework based on your store’s actual requirements rather than technology trends.
Get Professional Liquid Development Support
If you need custom Liquid work beyond what you can confidently build yourself, working with a specialist Shopify developer saves time and avoids costly mistakes in production code.
Our team at KolachiTech provides expert Shopify theme development services and Shopify custom development services for merchants who need bespoke Liquid customisation done correctly the first time.
For stores that need a complete custom theme design alongside Liquid development, our Shopify store design service delivers a fully custom storefront built on clean, performant Liquid code.
Book a free consultation to discuss your theme customisation requirements.
Conclusion
Liquid is an approachable templating language that gives you complete control over how your Shopify theme looks and behaves. Start with the fundamentals: objects for output, tags for logic, and filters for transformation.
Always duplicate your theme before editing. Test on a preview before publishing. Make one change at a time.
With these habits and the syntax foundations covered in this shopify liquid tutorial, you can make meaningful, targeted customisations to your theme without putting your live store at risk.
Frequently Asked Questions
Q: What is Shopify Liquid? A: Shopify Liquid is an open-source templating language used to build Shopify themes. It uses objects, tags, and filters embedded in HTML files to dynamically render store data like product titles, prices, and descriptions.
Q: Do I need to know Liquid to customize a Shopify theme? A: For changes through the theme editor, no coding is needed. For custom changes beyond what the editor supports, such as new sections, conditional content, or layout changes, Liquid knowledge is required.
Q: How do I edit Liquid files in Shopify? A: Go to Shopify Admin > Online Store > Themes > three-dot menu on your active theme > Edit code. This opens the full theme code editor with access to all Liquid template files.
Q: What is the difference between a Liquid tag and a Liquid object? A: An object outputs store data using double curly braces: {{ product.title }}. A tag controls logic and does not produce visible output by itself, using curly brace percent signs: {% if product.available %}.
Q: Is it safe to edit Liquid theme files directly? A: Yes, if you follow safety practices: always duplicate your theme first, test changes using theme preview before publishing, and edit one file at a time.
Q: What are Liquid filters in Shopify? A: Filters modify the output of objects using a pipe character. For example, {{ product.price | money }} formats the price using the store’s currency settings. Shopify provides commerce-specific filters for images, money, URLs, and more.
Q: What is the difference between a Shopify section and a snippet? A: A section is a full page component with a JSON schema making it editable in the theme editor. A snippet is a reusable code fragment without a schema, included in other files using the render tag for repeating UI elements like product cards.
