Liquid theme components
On this page
Components are reusable Liquid templates, much like snippets, but with one important difference: a component can reload itself from the server without a full page refresh. This lets you keep part of a page up to date as the shopper interacts with your store. For example, it can refresh the cart total after an item is added, or update the order summary when a voucher is applied.
This article is for theme developers. It assumes you are comfortable creating theme templates and writing Liquid.
Overview
A component has two parts:
- The component template — the Liquid that produces the component’s markup. You create it as a theme template with a key that starts with
components/, in the same way you create a snippet. - The
componenttag — the tag you place in another template to render the component:{% component "name" %}.
When the page first loads, the component renders inline just like a snippet. StoreConnect also wraps its output in a small container that holds an encrypted token describing the component. When a matching browser event fires, the client requests a fresh copy of the component from the server and swaps it into the page in place, with no full reload and no custom JavaScript required.
Creating a component template
Create a new theme template and give it a Key that starts with components/. The rest of the key can be anything you like, as long as it is unique for the theme. For example, to create a component named cart, use the key:
components/cart
The Content is the Liquid that renders the component. Here is a minimal example:
```liquid
{%- if current_cart != blank and current_cart.items.size > 0 %} {%- render “shared/cart/items”, source: current_cart %} {%- render “shared/order_total”, source: current_cart %} {%- else %}
{{ "cart.empty_msg" | t }}
{%- endif %} ```
You can nest components in folders by including slashes in the key, for example components/checkout/vouchers or components/orders/order_summary.
Rendering a component
Use the component tag in any template to render the component:
```liquid
{% component “cart” %} ```
You can pass parameters to the component the same way you pass them to a snippet:
```liquid
{% component “orders/order_summary”, source: current_cart %} ```
Inside the component, read a parameter with default:
```liquid
{% liquid default source: nil %} ```
See the Component tag reference for the full tag syntax.
Reloading a component on an event
Add the reload option to tell a component which browser events should trigger it to refresh. reload takes a space-separated list of event names:
```liquid
{% component “cart”, reload: “sc.cart-updated” %} ```
When an event named sc.cart-updated fires anywhere on the page, the component fetches a fresh copy from the server and replaces itself in place. You can list more than one event:
```liquid
{% component “cart-menu”, reload: “sc.cart-updated sc.voucher-applied sc.voucher-removed” %} ```
StoreConnect’s built-in interactions dispatch events you can listen for, including:
| Event | Fires when |
|---|---|
sc.cart-updated |
An item is added to, removed from, or changed in the cart |
sc.voucher-applied |
A voucher is applied |
sc.voucher-removed |
A voucher is removed |
For example, the built-in cart form dispatches sc.cart-updated on a successful update via data-success="sc.cart-updated". Any component listening for that event then reloads automatically. You can also dispatch your own custom events from your theme’s JavaScript. Any component whose reload list includes that event name will refresh.
Loading a component later
Two options let a component load after the initial page render instead of during it. This keeps the first render fast when a component is slow to build or is not immediately visible.
defer— the component renders a loading placeholder first, then fetches its real content automatically as soon as the page loads.
```liquid
{% component “checkout/shipping_rates/page”, defer: true %} ```
lazy— the component renders empty and only fills in when one of itsreloadevents fires. Use it for content that should not appear until something happens.
```liquid
{% component “cart”, reload: “sc.cart-updated”, lazy: true %} ```
Persisting data across reloads with context
Parameters you pass to a component are only available on the first render. When a component reloads from the server, it no longer has access to those parameters. The reload request only carries the component’s stored context.
To keep a value available across reloads, store it with the context tag. The context is saved in the component’s encrypted token and restored on every reload.
The built-in order summary component demonstrates this pattern. On first render it receives a source parameter and saves an identifier into the context; on reload it reads that identifier back from the context and re-queries the record:
```liquid
{% liquid default source: nil
if source == nil # A reload: no parameters, so rebuild from stored context case context.source_object when “Cart” query “s_c__cart__c” as results, s_c__sc_id__c: context.source_id when “Order” query “order” as results, s_c__sc_id__c: context.source_id endcase if results and results.size > 0 assign source = results.first | cast: context.source_object endif else # First render: store what we need for later reloads capture source_object echo source endcapture context source_object: source_object, source_id: source.id endif -%} ```
Knowing whether a component is reloading
A reloaded variable is available inside the component. It is false on the first render and true on every subsequent server reload. Use it to skip work that only needs to happen once:
```liquid
{%- unless reloaded == true %} {%- comment %} runs on first render only {% endcomment %} {%- endunless %} ```
Showing flash messages after a reload
When an event triggers a reload, you can also show an alert or notice by including a data object in the event detail. StoreConnect reads alert, notice, or flash from the event and dispatches the matching sc.alert or sc.notice message. This lets a single interaction both refresh a component and surface feedback to the shopper.
How it works
Understanding the request cycle helps when debugging:
- On first render, StoreConnect renders the component inline and wraps it in a container that carries an encrypted token. The token holds the component name, its stored context, the shopper’s session, and the list of reload events.
- The client watches the page for the events named in
reload. When one fires (or immediately, for a deferred component), it sends the token to StoreConnect. - StoreConnect decrypts the token, checks that it belongs to the current session, re-renders the component with
reloaded: trueand the restored context, and returns the fresh markup, which the client swaps into place.
Because the token is tied to the shopper’s session, a component reload cannot be triggered on behalf of another session.
Related articles
- Theme Templates — how to create templates and snippets
- Component tag reference — full
componenttag syntax and options - Context tag reference — storing state that survives a reload
Was this article helpful?
Thanks for your feedback! It helps us improve our docs.