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 runnpm install.
unpkg (recommended)
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.
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.
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 onexecute(), or both — per-query context shallow-merges with and overrides the global context.
Context fields:
CartProduct:
CustomerContext:
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:
- Confirm the Layers app is installed and connected in Shopify admin.
- Trigger a resync from Settings → Integrations in the Layers dashboard so the metafield is written to the shop. See Collection & app metafields.
- Re-render the theme and confirm the metafield now returns a non-empty value.
"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
sortsconfig and confirm the exactcodevalues match your dashboard’s sort orders. - Check the
scopeon each sort. A sort scoped to['collection']isn’t valid onclient.search()and vice versa. - Omit
sortfromexecute()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
Nin yourfacetsarray. - Attribute codes are case-sensitive and must exactly match the attribute code shown in the Layers dashboard (for example,
options.color, notOptions.Color). - Facets you no longer use in the dashboard should also be removed from
createClient().