Liquid tags reference
On this page
Liquid tags use the {% %} syntax and perform actions rather than output values. StoreConnect extends standard Liquid with its own tags for template structure, data querying, HTTP responses, caching, and more.
Tags come in two forms:
- Simple tags — self-contained:
{% tag_name options %} - Block tags — open/close pair wrapping content:
{% tag_name %}...{% endtag_name %}
For the index of StoreConnect-specific tags grouped by category, see Liquid tags.
Control flow
if / elsif / else
Executes a block when a condition is true.
```liquid
{% if product.available %}
In stock
{% elsif product.pricing.on_sale? %}
On sale
{% else %}
Out of stock
{% endif %} ```
Comparison operators: ==, !=, >, <, >=, <=, contains
Logical operators: and, or
```liquid
{% if product.available and product.pricing.price < 100 %}
Affordable and in stock
{% endif %}
{% if product.tags contains “sale” %} Sale {% endif %} ```
unless
Executes a block when a condition is false. Does not support elsif.
```liquid
{% unless current_customer %} Log in {% endunless %} ```
case / when
Switch statement for matching values.
```liquid
{% case current_checkout_step %} {% when “customer_information” %} {% render “checkout/customer_information” %} {% when “shipping_information” %} {% render “checkout/shipping_information” %} {% else %} {% render “checkout/default” %} {% endcase %} ```
Multiple values: {% when "monday", "tuesday", "wednesday" %}
Iteration
for
Iterates over a collection.
```liquid
{% for product in all_products %}
{{ product.name }}
{% endfor %} ```
Parameters:
| Parameter | Description |
|---|---|
limit |
Maximum iterations: {% for item in items limit: 5 %} |
offset |
Skip items: {% for item in items offset: 3 %} |
reversed |
Reverse order: {% for item in items reversed %} |
Range: {% for i in (1..10) %}{{ i }}{% endfor %}
forloop object:
| Property | Description |
|---|---|
forloop.index |
Current iteration (1-based) |
forloop.index0 |
Current iteration (0-based) |
forloop.rindex |
Remaining iterations (1-based) |
forloop.rindex0 |
Remaining iterations (0-based) |
forloop.first |
True on first iteration |
forloop.last |
True on last iteration |
forloop.length |
Total number of iterations |
Empty fallback:
```liquid
{% for product in collection %} {{ product.name }} {% else %}
No products found
{% endfor %} ```
break / continue
```liquid
{% for item in items %} {% if item.hidden? %}{% continue %}{% endif %} {% if forloop.index > 10 %}{% break %}{% endif %} {{ item.name }} {% endfor %} ```
tablerow
Generates HTML table rows.
```liquid
```
Parameters: cols, limit, offset, range
Variable
assign
Assigns a value to a variable.
```liquid
{% assign my_variable = “Hello” %} {% assign product_count = all_products.size %} {% assign is_sale = product.pricing.on_sale? %} ```
capture
Captures rendered content into a variable.
```liquid
{% capture full_name %}{{ current_customer.firstname }} {{ current_customer.lastname }}{% endcapture %}
Welcome, {{ full_name }}
```
increment / decrement
Creates and increments/decrements a named counter. The counter is independent of variables with the same name.
```liquid
{% increment counter %} {% increment counter %} {% increment counter %} ```
default
Sets default values for variables that are not already defined. Only runs if the variable doesn’t exist — does not override passed values. Commonly used at the top of snippets to define parameter defaults.
```liquid
{% default title: “Untitled”, show_price: true, max_items: 10 %} ```
new
Creates new objects.
UUID:
```liquid
{% new UUID my_id %} {{ my_id }} ```
List:
```liquid
{% new List my_list %} {% new List my_list = “[1,2,3]” %} ```
Map:
```liquid
{% new Map my_map %} {% new Map config = ‘{“theme”:”dark”}’ %} {{ config.theme }} ```
Random number:
```liquid
{% new Rand dice, min: 1, max: 6 %} {{ dice }} ```
struct
Creates a validated structured object.
```liquid
{% struct my_obj = “struct_name”, key: “value”, count: 42 %} ```
Template
comment
Prevents content from rendering.
```liquid
{% comment %} This won’t be output {% endcomment %}
{%- comment -%} Inline comment {%- endcomment -%} ```
Inline form: {%# This is a comment %}
raw
Temporarily disables Liquid processing so {{ }} and {% %} syntax passes through as literal text.
```liquid
{{ this will not be processed }}
```
render
Renders a snippet or partial template.
```liquid
{% render “header” %} {% render “products/card”, product: product, show_price: true %} ```
Variables are passed as named parameters. The snippet runs in its own scope — only passed variables are available.
layout
Specifies which layout wraps the current page template. If omitted, the default theme.liquid layout is used.
```liquid
{% layout “account” %} ```
require
Loads a CSS or JavaScript asset. Automatically deduplicates — the same asset is only loaded once per page regardless of how many templates request it.
```liquid
{% require “styles/theme.css” %} {% require “scripts/theme.js” %} ```
Alias: {% resource_path "styles/theme.css" %}
header
Sets HTTP response headers.
```liquid
{% header name: “Content-Type”, value: “application/json” %} {% header name: “Cache-Control”, value: “public, max-age=3600” %} ```
component
Renders a reusable component with support for lazy loading and event-driven reload.
```liquid
{% component “cart”, reload: “sc.cart-updated” %} {% component “checkout/vouchers”, reload: “sc.voucher-applied sc.voucher-removed”, lazy: true %} ```
| Parameter | Description |
|---|---|
| First argument | Component template name (in components/ directory) |
reload |
Space-separated event names that trigger a reload |
lazy |
If true, loads asynchronously after page load |
| Additional params | Passed to the component template |
form
Wraps a block in an HTML form with CSRF protection and field definitions.
```liquid
{% form “add-to-cart”, product: current_product %} {% endform %} ```
Inside the block, the form variable provides field definitions and errors. See Theme forms and Liquid forms reference.
paginate
Paginates a collection with configurable page size and navigation window.
```liquid
{% paginate all_products by 20, window: 5 %} {% for product in all_products %} {{ product.name }} {% endfor %}
{% if paginate.pages > 1 %} {% for part in paginate.parts %} {% if part.gap? %}… {% elsif part.current? %}{{ part.page }} {% else %}{{ part.page }} {% endif %} {% endfor %} {% endif %} {% endpaginate %} ```
| Parameter | Description |
|---|---|
by |
Items per page (required) |
as |
Custom URL parameter name (default: "page") |
window |
Number of page links on each side (default: 5) |
paginate drop properties: page_size, current_page, pages, records, current_offset, next, previous, first, last, parts
Part properties: url, page, current?, gap?
cache
Caches a block of rendered HTML for a configurable duration.
```liquid
{% cache “product-card”, items: [current_product, current_store], expires_in: 60 %} {% render “products/card”, product: current_product %} {% endcache %} ```
| Parameter | Description |
|---|---|
| First argument | Cache key name (required) |
items |
Array of objects used to generate the cache key |
expires_in |
Expiration in seconds |
race_condition_ttl |
Race condition TTL in seconds |
process_event
Processes an event object and injects its methods into the template context.
```liquid
{% process_event order_event %}
{{ event_type }}: order #{{ order_number }}
{% endprocess_event %} ```
Data & integration
query
Fetches records from the StoreConnect data store and assigns them to a variable.
```liquid
{% query ‘Product2’ as featured, Featured__c: true order by ‘Name asc’ %} {% for record in featured %} {{ record.Name }} {% endfor %} ```
Syntax: {% query 'ObjectName' as variable [, field: value] [order by 'field asc|desc'] %}
Records from {% query %} are raw record objects. Use | cast: "TypeName" to convert them to drops with full property access.
```liquid
{% query ‘Product2’ as records, IsActive: true order by ‘CreatedDate desc’ %} {% for record in records %} {% assign product = record | cast: “Product” %} {{ product.name }} — {{ product.pricing.price | money }} {% endfor %} ```
See Liquid query for full usage guidance.
api
Makes an outbound HTTP request to an external service.
```liquid
{%- new Map post_data -%} {%- assign post_data = post_data | set_key: “event”, “signup” | set_key: “email”, current_customer.email -%} {% api url: “https://api.example.com/track”, method: “post”, data: post_data %} {% if response.status == 200 %} <p>{{ response.body.message }}</p> {% endif %} {% endapi %} ```
| Parameter | Description |
|---|---|
url / endpoint |
Target URL (required) |
method |
HTTP method: get, post, put, patch, delete (default: get) |
data |
Request body — must be a Map variable, not inline JSON |
headers |
Custom HTTP headers |
username / password |
Basic authentication |
bearer |
Bearer token |
async |
Run in background (forced true inside {% final %}) |
Response object: response.status, response.body, response.headers. JSON responses are automatically parsed. Async requests don’t expose response data.
State management
session
Stores values in the user’s session, persisting them across requests.
```liquid
{% session last_viewed: product.id, preference: “compact” %} ```
Access stored values with session_variables:
```liquid
{{ session_variables.last_viewed }} {{ session_variables.preference }} ```
context
Sets variables scoped to a component. Only effective inside component templates. Context variables persist across reloads and don’t leak to parent or sibling components.
```liquid
{% context product_id: current_product.id, show_details: true %} ```
Controller lifecycle
These block tags run only during a specific phase of a Liquid controller’s execution. See Liquid controllers guide for full usage.
before
Runs before the page template renders.
```liquid
{% before %} {% params product_id: current_request.params.id %} {% action “cart.add”, product_identifier: product_id, quantity: 1 %} {% endbefore %} ```
after
Runs after the main controller action.
```liquid
{% after %} {% redirect to: “/cart”, notice: “Item added” %} {% endafter %} ```
final
Runs after the response is sent. API calls here are automatically async.
```liquid
{% final %} {%- new Map payload -%} {%- assign payload = payload | set_key: “event”, “purchase” -%} {% api url: “https://analytics.example.com/track”, method: “post”, data: payload %}{% endapi %} {% endfinal %} ```
Action tags (inside phases)
These tags are valid only inside {% before %}, {% after %}, or {% final %} blocks.
{% params %} — reads request parameters into controller params.
{% variables %} — sets template variables available in the page template.
{% redirect %} — redirects and stops execution. Options: to, notice, alert, status.
{% respond %} — sends a custom HTTP response. Options: status, body, json.
{% update %} — updates a custom data field on an object.
{% action %} — executes a named action. Cart: cart.add, cart.update, cart.remove, cart.empty, cart.select, cart.clone. Shipping: shipping.set. Pricebook: pricebook.set, pricebook.clear. Promotion: promotion.apply, promotion.remove, promotion.clear.
Debugging
debug
Logs variable values to the session debug output.
```liquid
{% debug product_id: product.id, cart_items: current_cart.item_count %} ```
timer
Measures and logs the execution time of a template block.
```liquid
{% timer “product_list_render” %} {% for product in all_products %} {% render “products/card”, product: product %} {% endfor %} {% endtimer %} ```
Whitespace control
Add - to tag delimiters to strip surrounding whitespace:
```liquid
{%- assign x = “hello” -%} {%- if true -%}Content{%- endif -%} ```
Was this article helpful?
Thanks for your feedback! It helps us improve our docs.