← The Ultimate Guide to Succeeding on Shopify
Publié07 Aug 2023
AuteurFlorian POHL
Lecture8 min

Shopify Liquid, the Theme Language

In brief Liquid is the template language for Shopify themes: it runs server-side and injects your data, products, prices, and inventory into the HTML seen by the visitor. It's built on three complementary components: ...

In brief

Liquid is the template language for Shopify themes: it runs server-side and injects your data, products, prices, and inventory into the HTML seen by the visitor. It's built on three complementary components: objects that display data, tags that carry logic, and filters that transform the rendering. Its simple uses, like modifying text, applying a filter, or adding a small condition, are within reach for non-developers, while complex loops, cart, and checkout functionalities require a true specialist. At Stellar, we've been using Liquid since 2018 with a consistent approach: starting from a solid existing theme and reserving custom development for customizations that truly increase conversion, rather than recoding everything from scratch.

Shopify Liquid is the open-source template language that builds the platform's themes. Its role can be summarized in one sentence: it connects your store data (products, collections, cart, customer) to the HTML displayed on the screen, and decides what to show, to whom, and in what order. Without Liquid, a Shopify theme would just be a static page, unable to display the correct price or inventory in real-time.

Every time a product title, a promotion badge, or an inventory counter updates automatically, Liquid is working behind the scenes. Understanding it, even without becoming a developer, gives you control over your store's appearance and behavior. This page provides you with the concrete basics, with ready-to-read code, and then helps you understand where healthy tinkering ends and developer work begins.

At Stellar, we've been using Liquid since our beginnings in 2018. Our approach after delivering over 100 stores: we do custom development, but we almost always start from a solid existing theme rather than recoding everything from a blank page. Rewriting a functionality in Liquid that is already native to a good theme is a waste of client budget. Custom development is even more valuable when it focuses on where it truly changes the experience and conversion.

Liquid, what is it exactly?

Liquid is a template language: it doesn't calculate, it assembles. Shopify created it in 2010, then made it open source, so it's now found far beyond e-commerce. In a store, it runs server-side, before the page arrives in the browser: the visitor never sees the Liquid code, only its HTML output.

This is the key difference from JavaScript, which executes in the browser once the page has loaded. Liquid determines the page's content (which product, what price, what availability), while JavaScript adds interactivity on top (a menu that opens, a cart that updates without reloading). The two complement each other; they are not in opposition.

In practice, Liquid serves three purposes:

  • Display dynamic data: a product name, its price, an image, the first name of the logged-in customer.
  • Decide with logic: show a block only if the product is on sale, in stock, or tagged in a certain way.
  • Transform the display: format a price in euros, shorten a description, resize an image on the fly.

These three uses correspond exactly to the three building blocks of the language. To place Liquid within the overall ecosystem, our complete guide to succeeding on Shopify puts themes in the broader context of the platform.

The 3 components: objects, tags and filters

All of Liquid comes down to three syntax elements. Objects display data, tags carry logic, and filters modify the rendering. Once you understand this trio, you'll be able to read 90% of Shopify themes without difficulty.

Objects: displaying data

An object is recognized by its double curly braces. It refers to a store's data and displays it as is. It is the simplest and most used building block.

{{ product.title }}
{{ product.price | money }}
{{ collection.title }}
{{ customer.first_name }}

Here, product, collection or customer are objects provided by Shopify depending on the context of the page. Some custom data passes through metafields: we detail their display in our guide dedicated to Shopify metafields and their display in Liquid.

Tags: controlling logic

A tag is recognized by the curly brace followed by a percentage sign. It doesn't display anything by itself: it decides. Condition, loop, variable assignment, it's the brain of the theme.

{% if product.available %}
  In stock, ships within 48 hours
{% else %}
  Back in stock soon
{% endif %}

{% for produit in collection.products %}
  {{ produit.title }}
{% endfor %}

The if condition displays a block only if a rule is true. The for loop repeats a block for each element in a list, for example, each product in a collection. These are the two tags you'll encounter most often.

Filters: transforming the display

A filter is placed after a vertical bar, inside an object. It takes a value and transforms it before display, without touching the original data. They can be chained.

{{ product.price | money }}
{{ product.title | upcase }}
{{ article.published_at | date: '%d/%m/%Y' }}
{{ product.description | strip_html | truncate: 120 }}

On the last line, two filters are chained: strip_html removes HTML tags from the description, then truncate cuts it to 120 characters. It's this chaining logic that makes filters so practical for everyday use.

Cheat sheet: 15 useful Liquid filters

Here are the filters our developers use most often, those that cover the vast majority of store needs. Keep this table handy when you open a theme file.

Filter What it does Example
money Formats an amount according to the store's currency {{ 1990 | money }} gives €19.90
money_without_trailing_zeros Like money, but without unnecessary cents {{ 2000 | money_without_trailing_zeros }} gives €20
date Formats a date to the desired format {{ article.published_at | date: '%d/%m/%Y' }}
default Displays a fallback value if the data is empty {{ product.title | default: 'Untitled' }}
truncate Truncates text to a number of characters {{ product.description | truncate: 120 }}
truncatewords Truncates text to a number of words {{ product.description | truncatewords: 20 }}
strip_html Removes all HTML tags from text {{ product.description | strip_html }}
escape Secures text displayed in HTML {{ comment.author | escape }}
upcase / downcase Converts text to uppercase or lowercase {{ product.vendor | upcase }}
capitalize Capitalizes the first word {{ product.type | capitalize }}
image_url Generates the URL of an image at the requested size {{ product.featured_image | image_url: width: 600 }}
asset_url Returns the URL of a theme file {{ 'logo.svg' | asset_url }}
size Counts the elements in a list or text {{ cart.items | size }} item(s)
plus / minus / times Performs a simple calculation {{ product.price | times: 2 }}
handleize Transforms text into a clean URL identifier {{ 'Robe d\'été' | handleize }} gives robe-d-ete

The complete and up-to-date list lives in the official Shopify Liquid documentation, a reference to keep bookmarked.

Practical case: a conditional "New" badge

Nothing beats a complete example. Objective: display a "New" badge on product pages, without a paid app and without overloading the theme. Two approaches, from the simplest to the most automatic.

Approach 1, by tag. You add the "new" tag to the relevant products from the admin, and the theme displays the badge accordingly. Simple, manually controlled, ideal for occasional highlights.

{% if product.tags contains 'new' %}
  <span class="badge badge--new">New</span>
{% endif %}

Approach 2, by date. The badge appears automatically for any product created less than 14 days ago, then disappears on its own. No tags to manage, but a bit more logic.

{% assign now = 'now' | date: '%s' | plus: 0 %}
{% assign creation = product.created_at | date: '%s' | plus: 0 %}
{% assign age = now | minus: creation %}
{% if age < 1209600 %}
  <span class="badge badge--new">New</span>
{% endif %}

In the second block, we convert the current time and the product's creation date into seconds, calculate the difference, then compare it to 1,209,600 seconds, which is 14 days. This is exactly the kind of discreet automation that saves time in the long run: no one has to remember to remove the tag.

The style of the badge (color, position, roundedness) is then managed with CSS in the theme. It's also at this stage that a developer's eye avoids pitfalls: a misplaced badge that breaks the product grid on mobile, or a loop that's too heavy on a collection with several hundred references.

Do it yourself or hire a developer?

The good news: some parts of Liquid are perfectly accessible without being a developer. The limit lies where an error can break the display in production or slow down the store. Here's our dividing line, the one we apply internally.

You can do it yourself Better to entrust to a developer
Modify text or labels in a theme file Create or redesign an entire section with its settings
Add a simple filter (money, date, truncate) Write loops on large catalogs without slowing down performance
Set a short if/else condition and test it in pre-production Touch the cart, checkout, or JSON templates
Duplicate an existing block that already works Integrate business logic or a third-party app in depth

Our safety rule is simple: duplicate the theme before any intervention, and test on the copy. A published theme is modified without a safety net, and a forgotten curly brace is enough to display an error to your visitors.

When Liquid is no longer sufficient, for example for a store with a very rich interface or performance needs, the next step is often a decoupled architecture: we explain this in our guide on the Hydrogen framework, the React alternative to Liquid. For truly impactful custom personalizations, you can also rely on our Shopify development team: we start from your current theme to invest only where custom development creates value.

Foire aux questions

No, not for everyday use. Displaying a piece of data, writing a simple condition, or applying a filter can be learned in a few hours, because the syntax is readable and close to natural language. The difficulty comes with advanced logic (nested loops, performance on large catalogs, JSON templates), which is then a job for a developer.

Consultation offerte

Vous avez un projet e-commerce
à nous confier ?

Réservez un call gratuit de 30min avec un expert Shopify

  • Diagnostic express
  • Pistes concrètes
  • Devis sous 48 h
Réserver 30 min