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 @preact/signals-core import into a sibling unpkg URL, 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 (@2), minor (@2.0), or exact (@2.0.3) tag — for example, https://unpkg.com/@commerce-blocks/sdk@2?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 dependency 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 client across modules

createClient registers the client in a singleton, so any later <script type="module"> block can pull it back with getClient. 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@2?module" /> to your <head> so the browser starts fetching it during HTML parse instead of waiting for the first <script type="module"> to execute.

Configuration

Required configuration

Sort: Facet:
Every sorts[].code and facets[].code must match a sort order or attribute that exists in your Layers dashboard. The server validates these on each request. If a value is wrong or stale, execute() returns an ApiError whose message reads "The selected sort order code is invalid." or "The selected facets.N is invalid." (where N is the zero-based index of the offending facet). Fix these by updating the code values passed to createClient() to match your dashboard configuration. See Troubleshooting.

Optional configuration

Context

Pass market and shopper context to personalize results across all controllers. Set it globally on the client config, per-query on execute(), 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).

Product configuration

Swatch:

Transforms and filter aliases

Transforms post-process results before caching. Filter aliases map URL-friendly keys to API property names. Once configured, transforms and aliases are applied automatically:

Cache configuration

Singleton access

After initialization, access the client anywhere:

Important notes

All SDK methods return a Result type instead of throwing exceptions. Always check for result.error before accessing result.data.

Troubleshooting

401 Unauthorized on the first request

If the first execute() returns an ApiError with status 401 (for example, POST /api/storefront/v1/browse/frontpage 401), the token passed to createClient() 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 execute() doesn’t match any sorts[].code you registered with createClient(), or the registered code no longer exists in the Layers dashboard.
  • Log your sorts config and confirm the exact code values match your dashboard’s sort orders.
  • Check the scope on each sort. A sort scoped to ['collection'] isn’t valid on client.search() and vice versa.
  • Omit sort from execute() to fall back to the collection’s default sort order or the first configured sort.

"The selected facets.N is invalid."

The facets[N] in your createClient() config references an attribute that isn’t configured as a facet in Layers. N is the zero-based index of the offending facet.
  • Remove or fix the entry at index N in your facets array.
  • Attribute codes are case-sensitive and must exactly match the attribute code shown in the Layers dashboard (for example, options.color, not Options.Color).
  • Facets you no longer use in the dashboard should also be removed from createClient().