Skip to content
Log in

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 component tag — 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 its reload events 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:

  1. 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.
  2. 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.
  3. StoreConnect decrypts the token, checks that it belongs to the current session, re-renders the component with reloaded: true and 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.

Was this article helpful?

Was this article helpful?