Skip to main content
Tutorial

Shopify Standard Storefront Events and Actions: Theme Integration Guide

Shopify's new standard storefront communication layer lets themes emit predictable commerce events while apps and agents call cart actions across Liquid storefronts. Here's how to adopt it safely.

5 min read
ShopifyJavaScriptStorefront EventsTheme Development

Shopify released standard storefront events and actions on June 17, 2026. They give Liquid storefronts a consistent communication layer between themes and the apps or agents running on them.

The direction is easy to remember:

  • Themes emit events when commerce interactions happen.
  • Apps and agents call actions when they need the storefront to do something.

Before this standard, an integration often inspected theme-specific DOM, patched fetch, or maintained separate adapters for Dawn, Horizon, and custom themes. Standard names and payloads make one integration portable across storefronts.

Events: the theme reports what happened

Events are bubbling DOM events with a shopify: prefix. Examples include:

  • shopify:page:view
  • shopify:product:view
  • shopify:collection:view
  • shopify:cart:lines-update
  • shopify:search:update

The theme is responsible for emitting the appropriate event and payload when its own UI creates the interaction. Consumers subscribe with normal browser JavaScript and receive commerce data directly, reducing the need for a follow-up API request.

Load Shopify's standard-events library

Shopify hosts the event classes on its CDN. A module-based theme can register the package in an import map in theme.liquid:

<script type="importmap">
  {
    "imports": {
      "@shopify/standard-events": "https://cdn.shopify.com/storefront/standard-events.js"
    }
  }
</script>

Then import only the classes your module needs:

import { PageViewEvent } from '@shopify/standard-events';

document.addEventListener('DOMContentLoaded', () => {
  document.dispatchEvent(new PageViewEvent({
    page: {
      template: 'product',
      title: document.title,
      url: window.location.href,
    },
  }));
});

Shopify recommends dispatching shopify:page:view inside DOMContentLoaded so app scripts have time to attach listeners. Other events should originate at the most specific element that owns the interaction: a product section for product events, a cart drawer or cart page for cart events, and document for the page view. Because they bubble, a document-level listener can still observe them all.

For non-module themes, Shopify documents a direct module import assigned to a global:

<script type="module">
  import * as SE from 'https://cdn.shopify.com/storefront/standard-events.js';
  window.StandardEvents = SE;
</script>

Choose one loading model that matches the theme. Do not load duplicate copies simply to support both examples.

Listen without coupling to a theme

An app or theme feature can listen with the DOM API:

document.addEventListener('shopify:cart:lines-update', (event) => {
  const cart = event.detail;
  updateFreeShippingMessage(cart);
});

Use the event reference for the exact payload instead of assuming event.detail matches a legacy theme event. Standardization only helps when producers and consumers respect the documented contract.

Also avoid dispatching an extra cart event after calling Shopify.actions.updateCart. The action emits the matching standard event on success. Dispatching another copy causes analytics, recommendations, or UI listeners to handle one buyer action twice.

Actions: apps request storefront behavior

Actions work in the opposite direction. Shopify makes these calls available on every Liquid storefront:

  • Shopify.actions.updateCart
  • Shopify.actions.getCart
  • Shopify.actions.openCart

An integration can update or read the cart and open its UI without knowing whether the theme uses a drawer, modal, page, or another presentation. Every action has default behavior. A theme can configure that behavior to preserve its own no-reload cart experience.

For example, point successful cart events at the component that already handles re-rendering:

document.addEventListener('DOMContentLoaded', () => {
  Shopify.actions.updateCart.configure({
    eventTarget: () => document.querySelector('cart-items'),
  });
});

Place a theme's configuration above {{ content_for_header }} in the layout so it runs before app code. Only the first configure call for an action takes effect; later calls return false without changing the configuration.

If the theme needs custom rendering, configure a handler. This example preserves Shopify's cart write, refreshes a drawer through section rendering, and then returns the original result:

Shopify.actions.updateCart.configure({
  eventTarget: () => document.querySelector('cart-items'),
  async handler(defaultHandler) {
    const result = await defaultHandler();
    const response = await fetch(`${window.location.pathname}?sections=cart-drawer`);
    const sections = await response.json();
    document.querySelector('cart-drawer').innerHTML = sections['cart-drawer'];
    return result;
  },
});

Shopify.actions.openCart.configure({
  handler() {
    document.querySelector('cart-drawer')?.open();
  },
});

In a production theme, handle failed network responses, missing elements, focus movement, and cart status announcements. Replacing HTML is only one part of an accessible cart interaction.

Defaults and custom themes

Shopify's defaults recognize common Horizon- and Dawn-style cart implementations and can often refresh them without a page reload. A custom theme with a different cart structure can fall back to a full reload until you configure the actions.

That fallback is useful, but it should not hide incomplete adoption. Test add, change quantity, remove, note, discount, open-cart, and error states. Confirm that each operation:

  1. changes the cart once;
  2. updates all visible cart surfaces;
  3. emits one correct standard event;
  4. restores or moves focus logically;
  5. announces important feedback to assistive technology.

An incremental adoption plan

Start with observation, then mutation:

  1. Inventory the custom events your theme already dispatches.
  2. Map supported interactions to Shopify's standard event reference.
  3. Load the library once and emit page and view events from the documented targets.
  4. Add cart events for changes initiated by the theme itself.
  5. Test app listeners with Shopify's standard events inspector.
  6. Call the default cart actions in a development theme.
  7. Configure updateCart and openCart only where the theme's UI needs it.
  8. Remove DOM scraping or fetch interception only after equivalent behavior is verified.

Keep proprietary theme events temporarily if existing features still depend on them. A staged migration is easier to observe than changing event producers, cart rendering, and app integrations in one release.

The official overview, event dispatch guide, and action configuration guide define the current API. The June 2026 changelog entry explains why Shopify introduced the shared layer.

If cart markup begins as ordinary HTML, convert its structural Liquid with the HTML to Liquid converter, then use the manual review checklist before wiring JavaScript behavior.

Found this helpful?

Share it with your network!

Ready to Convert HTML to Liquid?

Try our free HTML to Liquid converter and build your Shopify themes faster.

Try HTML2Liquid Now