Variables
Creating and using variables with assign, capture, increment, and decrement.
Variables let you store values for later use in your template. They keep your code clean and avoid repeating the same expression.
assign
Create a variable with assign:
{% assign greeting = 'Welcome to our store' %}
<h1>{{ greeting }}</h1>You can assign the result of a filter:
{% assign sale_price = product.price | minus: 500 %}
<p>Sale: {{ sale_price | money }}</p>You can also assign values from other variables:
{% assign featured = collection.products.first %}
<h2>{{ featured.title }}</h2>Scope
Variables created with assign are available everywhere in the template after the point where they are created. They are not limited to a block or loop.
{% assign show_banner = true %}
<!-- Later in the template... -->
{% if show_banner %}
<div class="banner">New arrivals this week</div>
{% endif %}Variables do not carry over to other templates. Each template starts with a clean slate, plus the context objects provided by the platform (like product, collection, and store).
capture
Capture a block of rendered content into a variable:
{% capture product_url %}/products/{{ product.handle }}{% endcapture %}
<a href="{{ product_url }}">View Product</a>Everything between {% capture %} and {% endcapture %} is rendered and stored as a string. This is useful when you need to build a value from multiple parts.
A more complex example:
{% capture card_classes %}
product-card
{% if product.available %}in-stock{% else %}sold-out{% endif %}
{% if forloop.first %}featured{% endif %}
{% endcapture %}
<div class="{{ card_classes | strip }}">
<h3>{{ product.title }}</h3>
</div>The strip filter removes extra whitespace that the line breaks create.
increment
Create a counter that starts at 0 and goes up by 1 each time:
{% increment my_counter %}
{% increment my_counter %}
{% increment my_counter %}This outputs 0, 1, 2. Each call outputs the current value and then adds 1.
increment creates its own variable that is separate from variables made with assign. They do not conflict:
{% assign my_counter = 10 %}
{% increment my_counter %}
{% increment my_counter %}
{{ my_counter }}This outputs 0, 1, 10. The increment counter and the assign variable are independent.
decrement
Like increment, but counts down. Starts at -1:
{% decrement my_counter %}
{% decrement my_counter %}
{% decrement my_counter %}This outputs -1, -2, -3.
When to use each
| Tool | Best for |
|---|---|
assign | Storing a single value or filter result |
capture | Building a string from multiple parts or conditional logic |
increment | Simple counters that need to go up |
decrement | Simple counters that need to go down |
Most of the time, assign is all you need. Use capture when the value you want to store involves HTML or complex logic. Use increment and decrement rarely, mainly for numbering items outside of a loop.