subscribe(callback), state, and dispose(). You can wrap these in a framework-specific hook, store, or effect.
All examples below use a collection controller, but the same patterns apply to search, blocks, autocomplete, imageSearch, similarProducts, facets, sortOrders, searchContent, and createProductCard.
Vanilla JavaScript
Usesubscribe to drive DOM updates directly:
React
Wrapcontroller.subscribe and controller.state in a hook using useSyncExternalStore:
Vue
Use Vue’sref and onUnmounted to bridge SDK state:
Svelte
Usesubscribe to drive Svelte’s reactive $state:
Lit
Usesubscribe in connectedCallback / disconnectedCallback:
Alpine.js
Alpine pairs well with the SDK in zero-build Shopify themes. Boot the SDK from a CDN once, then use an Alpine component to expose controller state to your template. Hand the controller’ssubscribe callback into Alpine’s reactive $data and the DOM updates automatically as the SDK state changes.
Boot the SDK once
Load the SDK and Alpine from a CDN, then create the SDK in a single<script type="module"> block in theme.liquid. See Loading from a CDN for alternative CDNs and version pinning.
Collection component
Define an Alpine component that owns acollection() controller. The init() lifecycle hook creates the controller, wires subscribe into Alpine’s reactive state, and triggers the initial get(). destroy() tears the subscription and the controller down so navigating away never leaks state.
data.products, data.page, and data.totalPages straight off the SDK state and exposes them as Alpine reactive properties. Every subscribe emit re-renders the matching x-text, x-for, and x-show bindings.
Search component
The same pattern works for search. Create a newsearch controller when the shopper submits a query, and use autocomplete() for suggestions.
@input handler so you do not fire an autocomplete request on every keystroke.
ProductCard integration
ThecreateProductCard controller follows the same patterns. Here is a React example:
Using standalone subscribe
The SDK exports a subscribe utility that works with any controller: