Getting Started with Shopify Liquid

Liquid is Shopify's templating language. It runs on the server side and turns raw data from your store into HTML that browsers render. If you've ever looked at a Shopify theme file and seen curly braces everywhere, that's Liquid doing its job. The syntax looks a lot like Ruby, which helps if you've touched Ruby before, but it doesn't behave like Ruby in several important ways. I keep a reference document on my desk because even after years of writing Liquid, I still look things up constantly. The official Shopify docs are decent, but they scatter information across dozens of pages. A single cheat sheet saves you from tab-switching every five minutes. Variables are the simplest building block. You declare them with a hash, and you call them with double curly braces. {{ product.title }} outputs the product name. Filters modify the output, and you chain them with pipes. {{ product.title | upcase | truncate: 10 }} makes the title uppercase and cuts it to ten characters. That's the basic pattern you'll use repeatedly.

Control structures use the same curly brace syntax. {% if %}, {% elsif %}, and {% else %} handle conditional logic. {% for %} loops over collections. These are straightforward until you hit a case where the loop variable conflicts with an existing property, and then you spend an hour debugging something that should have been simple.

Common Object Handles You'll Actually Use

The product object is where most people start. product.title, product.price, product.description. But the object also contains arrays and nested objects that aren't obvious unless you've searched for them. product.variants gives you access to every variant, and each variant has its own variant.price, variant.sku, and variant.available. The nested structure means you can't just check product.available and assume the product is in stock. A product can be listed as available while every single variant is sold out. I ran into this exact problem last year when a client asked why their "out of stock" badge wasn't appearing on a product page. The product had one available variant and twenty sold out variants. product.available returned true because at least one variant was active. I had to loop through the variants and check each one individually. The fix took about twenty minutes once I knew what I was looking for. It would have taken three hours without the right reference material. The cart object works differently. cart.item_count gives you the total number of line items, not the number of unique products. If someone adds three quantities of the same item, that counts as three. cart.total_price returns the value in cents, which trips people up constantly. You need to divide by 100 and format it for display.

Get the Full Details

Shopify Liquid Cheat Sheet: Top Elements You Need to Know
Shopify Liquid Cheat Sheet: Top Elements You Need to Know

Collection objects have their own quirks. collection.products returns a maximum of 250 items unless you paginate properly. Shopify enforces this limit at the Liquid level, so there's no workaround within the template language itself. If you need more than 250 products in a collection view, you have to use pagination or a different approach entirely.

Filters and What They Actually Do

Liquid ships with a built-in set of filters. The ones you'll use every day include money, date, truncate, replace, and escape. {{ product.price | money }} formats the price with the correct currency symbol and decimal places based on your store settings. Don't skip this filter. Outputting raw prices without formatting will show cents as whole numbers and break your layout. date | date: '%B %d, %Y' formats dates. The format string uses Ruby's strftime conventions, not JavaScript's. That matters because the two systems use different letters for similar concepts. %m is month in strftime but minutes in JavaScript. If you're pulling dates from somewhere outside Liquid, keep that in mind. The handle filter converts a title into a URL-safe string. {{ 'Hello World!' | handle }} becomes hello-world. This is useful when you're generating URLs dynamically from user input or product titles.

There are less obvious filters too. json converts an object or array into a JSON string. {{ product | json }} outputs the entire product as formatted JSON. This is the quickest way to inspect an object's structure when you're debugging. It's not production-ready output, but it's invaluable for figuring out what properties actually exist on an object. Custom filters exist, but only if your theme app or a Shopify app defines them. There's no way to add custom filters from within a theme editor alone. You need an app with server-side code or access to the theme's code through the API. This limitation catches a lot of people off guard.

Shopify Liquid Cheat Sheet – The Pages Media
Shopify Liquid Cheat Sheet – The Pages Media

Loop Variables and Performance

Inside a {% for %} loop, Liquid provides several automatically generated variables. loop.index starts at one. loop.index0 starts at zero. loop.first and loop.last are booleans. loop.length gives you the total number of items in the collection. These save you from maintaining your own counters. Loop performance is worth considering. A {% for %} loop over a large collection executes every iteration on the server before sending HTML to the browser. If you're looping over a filtered product list with fifty items and running multiple conditionals inside each iteration, that adds up. Not dramatically, but noticeably on complex pages. I once worked on a theme where the homepage was loading slowly because a for loop was iterating over all products in a collection and running a nested conditional for each one. The collection had around 120 products. The page load time went from roughly 800 milliseconds to over three seconds. The fix was straightforward: limit the loop to the first 24 products and add a "view all" link. Page load dropped back to under one second.

Another thing to watch: Liquid doesn't support arbitrary mathematical operations the way a programming language does. You can't write {{ product.price + 5 }} and expect it to add five to the price. You can multiply prices by quantities, and you can use the math filter in some contexts, but general arithmetic is limited. If you need complex calculations, you're usually better off handling them in JavaScript after the page loads, or using a metafield combined with a small script.

Metafields and Modern Liquid

Metafields changed how people use Liquid significantly. Before metafields were available in templates, storing custom product data required hacky workarounds like stuffing values into product descriptions or using hidden fields. Now you can access metafields directly with {{ product.metafields.namespace.key }}. The namespace.key format requires you to know both parts. There's no auto-completion in the theme editor, and a typo in the namespace returns nothing rather than an error. I spent a good thirty minutes debugging a missing value once only to realize I had "custom" as the namespace instead of "custom_specs". Check your definitions in the Shopify admin before assuming the Liquid code is wrong. Metafield namespaces and keys are defined in the Shopify admin under Settings Custom Data. Products, variants, collections, and orders each have their own namespace. You can create namespaces up to 25 characters long and keys up to 100 characters. The values support text, numbers, dates, JSON, and references to other objects.

Liquid Cheat Sheet Shopify | Cheat Sheet Shopify – NJPDK
Liquid Cheat Sheet Shopify | Cheat Sheet Shopify – NJPDK

Where Liquid Falls Short

Liquid isn't a full programming language. It doesn't have functions you can define yourself, it doesn't support regular expressions in the native filter set, and it doesn't allow arbitrary variable assignment the way JavaScript does. You can set variables with {% assign %}, but those variables are local to the section or template where you define them. They don't persist across includes. Conditional logic gets cumbersome quickly. Nested ifs are possible but ugly and hard to maintain. I've seen themes with six levels of nested conditionals, and reading that code is painful. If your logic gets that complex, you're probably trying to do something in Liquid that should live in JavaScript or be handled by an app. Rendering performance is another constraint. Every Liquid tag and filter adds processing time. A heavily liquid-saturated page with dozens of loops, conditionals, and object accesses will load slower than a lean one. Shopify monitors this and will throttle excessively slow templates, though that's rare for typical stores. Still, keeping your templates as simple as possible is a good habit.

A Practical Workflow

Here's how I approach a new Liquid task. First, I open the relevant object in the debugger by adding {{ product | json }} to the template temporarily. This shows me the exact structure and available properties. I note the namespace and key for any metafields I need. I remove the debug output before publishing. Next, I write the Liquid markup with the right filters. I test the output visually in the browser, checking that prices render correctly, dates format as expected, and conditions trigger where they should. I verify edge cases: what happens when a product has no variants, when a collection is empty, when a metafield is unset. Finally, I check the page speed. If the new code adds noticeable latency, I look for ways to simplify. Often the answer is reducing loop iterations or moving logic client-side.

A good Shopify Liquid Cheat Sheet covers the common objects, the built-in filters, the loop variables, and the control structures. It should also note the limitations so you don't waste time trying to make Liquid do things it can't do. Most importantly, it should reflect how the language actually behaves in a real store, not just the theoretical syntax from the documentation. You can find community-maintained cheat sheets on GitHub and in various Shopify developer resources. The official Shopify docs also have a filtering reference that covers every built-in filter. Between those two sources, you should have everything you need for day-to-day theme development.

Your Ultimate Shopify Liquid Cheat Sheet – FTUF
Your Ultimate Shopify Liquid Cheat Sheet – FTUF