Skip to main content

Installation

Loading from a CDN

The SDK ships as a pure ES module with no Node-only dependencies, so it works in the browser with no build step. Use this when you’re integrating directly into a Shopify theme, a static HTML page, or any environment where you don’t run npm install. unpkg serves the published npm package directly. Add the ?module query string and unpkg rewrites the SDK’s imports into sibling unpkg URLs, so the browser resolves the entire module graph without a bundler.
Pin the version explicitly in production so a new release never silently changes behavior on your storefront. unpkg accepts a major (@3), minor (@3.0), or exact (@3.0.0) tag - for example, https://unpkg.com/@commerce-blocks/sdk@3?module. See the SDK changelog for the latest version.

esm.sh

esm.sh is an alternative ESM CDN that pre-bundles the SDK and its dependencies into a single file.

jsDelivr

jsDelivr mirrors npm with its own ESM transform. Use the +esm suffix to get a browser-compatible bundle.

Import maps

If you load multiple modules from a CDN and want to keep imports short, declare an import map once and use bare specifiers everywhere else:

Reusing the SDK across modules

createSDK registers the SDK in a singleton, so any later <script type="module"> block can pull it back with getSDK. This is the cleanest pattern for theme integrations where one snippet boots the SDK and many other sections consume it.
When pulling the SDK from a CDN, also add <link rel="modulepreload" href="https://unpkg.com/@commerce-blocks/sdk@3?module" /> to your <head>. The browser then starts fetching the module during HTML parse instead of waiting for the first <script type="module"> to execute.

Configuration

Required configuration

Optional configuration

Context

Pass market and shopper context to personalize results across all controllers. Set it globally on the SDK config, per-query on get(), or both. Per-query context shallow-merges with and overrides the global context.
Context fields: CartProduct: CustomerContext:
Use the global context for values that rarely change within a session (market, channel, customer profile). Use per-query context for values that vary by page or interaction (current cart, geo override).

Swatch configuration

Use swatches to map option values to colors or images. Swatches are matched by option name and value. Swatch:

Transforms

Transforms post-process response data before it is cached and returned. Once configured, transforms are applied automatically:

Cache configuration

The SDK uses an in-memory LRU cache with TTL eviction. In the browser, it persists cache values to localStorage automatically when a storage backend is available and supported. Pass a custom storage backend if you need a different store shape or prefix.

Singleton access

After initialization, access the SDK anywhere:

Important notes

All SDK methods return an ApiResult type ({ data, error }) instead of throwing exceptions. Always check for error before accessing data.

Troubleshooting

401 Unauthorized on the first request

If the first get() returns an ApiError with status 401 (for example, POST /api/storefront/v1/browse/frontpage 401), the storefrontAccessToken passed to createSDK() is missing, invalid, or expired. On Shopify, the storefront token is read from the shop metafield shop.metafields.layers.embed_settings.value.storefrontApiToken. If that metafield is empty or absent in your theme:
  1. Confirm the Layers app is installed and connected in Shopify admin.
  2. Trigger a resync from Settings → Integrations in the Layers dashboard so the metafield is written to the shop. See Collection & app metafields.
  3. Re-render the theme and confirm the metafield now returns a non-empty value.
If the metafield is still not populated after a resync, contact Layers support.

"The selected sort order code is invalid."

The sort you passed to get() does not match a sort order configured in Layers for the current collection, or the sort order no longer exists in the Layers dashboard.
  • Fetch available sort orders at runtime with sdk.sortOrders({ collectionHandle: 'shirts' }).
  • Use a code from the returned sort orders when calling collection.get() or creating a collection controller with sort.
  • Omit sort from get() to fall back to the collection’s default sort order.

"The selected facet is invalid."

A filterGroup you passed references an attribute that is not configured as a facet in Layers.
  • Fetch available facets at runtime with sdk.facets({ collectionHandle: 'shirts' }).
  • Attribute codes are case-sensitive and must exactly match the attribute code shown in the Layers dashboard (for example, your-attribute, not Your-Attribute).
  • Remove filters that reference attributes no longer configured as facets.