Skip to content
Log in

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

{% tablerow product in all_products cols: 3 %} {{ product.name }} {% endtablerow %}

```

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" %}

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?

Was this article helpful?