Key takeaways
- Liquid is Shopify’s templating language — it controls what content is rendered based on data from your store.
- Common use cases: show content based on product tags, customer tags, cart contents, metafields, or the current date.
- Basic Liquid syntax:
{% if %},{% unless %},{% for %},{{ variable | filter }}.- Add custom Liquid logic to section files or snippets in the code editor. Fudge can write it for you.
Liquid is what makes Shopify dynamic. It’s the templating language that connects your store’s data — products, collections, customers, cart — to the HTML that visitors see. Understanding the basics of Liquid logic lets you build conditional content, loops, and data-driven displays that go far beyond what the Theme Editor offers.
Liquid basics — what you need to know
Liquid has two types of tags:
Output tags {{ }} — display a value:
{{ product.title }}
{{ product.price | money }}
{{ customer.first_name }}
Logic tags {% %} — control the flow, not displayed directly:
{% if product.available %}
{% for item in cart.items %}
{% assign sale_price = product.price | times: 0.9 %}
Filters — transform output values using the | pipe:
{{ product.price | money }}
{{ product.description | strip_html | truncatewords: 30 }}
{{ 'base.css' | asset_url }}
Show content based on product tags
Product tags are a flexible way to mark products with attributes and then conditionally display content.
{% if product.tags contains 'new-arrival' %}
<span class="product-badge">New Arrival</span>
{% endif %}
{% if product.tags contains 'sale' %}
<span class="sale-badge">On Sale</span>
{% elsif product.tags contains 'clearance' %}
<span class="clearance-badge">Clearance</span>
{% else %}
<!-- No badge shown -->
{% endif %}
Use cases: badges for new arrivals, sale items, limited editions; showing or hiding sections based on product category; displaying care instructions only for specific product types.
Show content based on customer tags
Customer tags work the same way — you tag customer accounts in Shopify (Customers → select customer → Tags), then conditionally show content.
{% if customer %}
{% if customer.tags contains 'wholesale' %}
<p>Wholesale pricing: {{ product.price | times: 0.7 | money }}</p>
{% else %}
<p>{{ product.price | money }}</p>
{% endif %}
{% else %}
<p>{{ product.price | money }}</p>
{% endif %}
Use cases: different pricing for B2B vs retail customers, unlocking hidden content for VIP customers, showing loyalty points balance for members.
Show content based on metafields
Metafields store custom data attached to products, collections, customers, or your store. Once created (via the Shopify admin or an app), you can output them in Liquid.
{% if product.metafields.custom.ingredients %}
<div class="ingredients-section">
<h2>Ingredients</h2>
{{ product.metafields.custom.ingredients.value }}
</div>
{% endif %}
Creating metafields: Settings → Custom data → Products → Add definition. Set the namespace (e.g., custom) and key (e.g., ingredients).
Show content based on cart contents
You can access the current cart in any theme file:
{% if cart.item_count == 0 %}
<p>Your cart is empty.</p>
{% endif %}
{% if cart.total_price >= 5000 %}
<!-- Cart is $50+ (prices are in cents) -->
<p>You qualify for free shipping!</p>
{% else %}
{% assign remaining = 5000 | minus: cart.total_price %}
<p>Add {{ remaining | money }} more for free shipping.</p>
{% endif %}
Note: Shopify stores prices in cents (integers). 5000 = $50.00.
Show content based on date
{% assign now = 'now' | date: '%s' | plus: 0 %}
{% assign sale_end = '2026-12-31' | date: '%s' | plus: 0 %}
{% if now < sale_end %}
<div class="sale-banner">Holiday sale ends December 31!</div>
{% endif %}
date: '%s' converts a date to a Unix timestamp (seconds since 1970), making date comparisons straightforward.
For loops — iterating over collections or arrays
{% for product in collection.products limit: 4 %}
<div class="product-card">
<h3>{{ product.title }}</h3>
<p>{{ product.price | money }}</p>
</div>
{% endfor %}
Useful parameters:
limit: 4— only render 4 itemsoffset: 2— skip the first 2 itemsreversed— iterate in reverse order
Where to add custom Liquid logic
Section files (sections/your-section.liquid) — the right place for page-specific logic. Changes are scoped to that section.
Snippets (snippets/your-snippet.liquid) — reusable logic that can be included via {% render 'your-snippet' %} in multiple sections.
theme.liquid — for logic that needs to run on every page (like customer tag checks that affect site-wide behavior). Use sparingly.
Always work on a duplicate theme, and test after any Liquid change — a Liquid syntax error can render your entire page blank.
Unless — the opposite of if
{% unless %} is shorthand for “if not”:
{% unless customer %}
<a href="/account/login">Log in for member pricing</a>
{% endunless %}
Equivalent to {% if customer == false %} but more readable.
Assign and capture — creating variables
assign creates a simple variable:
{% assign discount_price = product.price | times: 0.8 %}
{{ discount_price | money }}
capture creates a variable from a block of content (can include HTML and Liquid):
{% capture size_label %}
{{ product.variants.first.option1 }} / {{ product.variants.first.option2 }}
{% endcapture %}
<span>{{ size_label }}</span>