{ data, error } controllers, except searchFeedback() and trackingEvent() which return a single direct { data, error } result. Controllers expose get(), subscribe(), and dispose().
get(query?) accepts query overrides only, not an options argument or AbortSignal. When you call get() again on the same controller, only the latest call updates its state and notifies subscribers. Earlier requests still run, and each returned promise resolves with its own result.
SDK instance creation
collection
Browse products in a collection.get() call accepts a shallow merge of the initial params, so you can change pagination, sort, or filters after the controller is created:
sdk.collection():
Dynamic linking
dynamicLinking.products pins products on the first page. Each entry is a { productId, position? } object, where productId is a product handle or a numeric product ID as a string:
dynamicLinking to the Browse API unchanged. position is the exact 1-based slot for that product on the first page, so in the example above summer-dress-blue lands at position 1 and product 8234567890123 at position 4, with regular results in positions 2 and 3. Products without a position are pinned in array order from the top of the page. If the same product appears more than once, the first explicit position wins. Products that don’t exist or aren’t available are skipped. If the store turns on out-of-collection linking, linked products that aren’t in the collection are also placed, and a position past the page size lands on a later page; send the same dynamicLinking value with every page request.
With the Layers app embed enabled, the Storefront Pixel adds dynamicLinking itself when a shopper lands with a utm_products URL parameter, so you only pass it for pins your theme decides on.
search
Execute a full-text search. The search query is fixed when the controller is created. You can then update pagination, filters, and sort withget().
search controller automatically prepares the query before execution and retries when the API returns a 425 (not prepared yet).
searchContent
Search for non-product content such as articles.autocomplete
Fetch search suggestions as the shopper types. Unlikesearch, get() accepts a new query each call.
suggest (deprecated)
suggest() is a debounced wrapper around autocomplete(). It is retained for v2 compatibility but is deprecated. New code should use autocomplete() with createDebounce() or your framework’s debouncing utility.
imageSearch
Search for products using an image ID returned byuploadImage().
imageData (a base64 string or Blob) and the SDK uploads it for each get() call.
uploadImage
Upload an image for visual search. The controller is uncached; eachget() call uploads the image again. Uploads are rate limited, so reuse the returned imageId in imageSearch() instead of re-uploading the same image.
similarProducts
Fetch products similar to a given product.blocks
Fetch product recommendations from a Layers block.anchorId is required for product and collection anchored blocks and omitted otherwise.
facets
Fetch facet counts for a collection at runtime.sdk.facets() replaces the facets array that was configured at SDK init in v2.
sortOrders
Fetch available sort orders at runtime.searchFeedback
Send feedback about search results.searchFeedback() is a direct, non-controller call.
trackingEvent
Send a custom analytics event.trackingEvent() is a direct, non-controller call.
eventType values are collection_view, product_click, product_view, product_impression, product_hover, product_touch, add_to_cart, search, autocomplete, and block_view.
TrackingEventInput also permits eventId, timestamp, sessionId, deviceId, attributionToken, variantId, collectionHandle, blockId, searchId, query, and position.
Subscribing to controller state
Usesubscribe or the controller’s subscribe method to react to state changes.
Disposing controllers
Calldispose() when a controller is no longer needed to clear subscriptions and reset its state. Pending results cannot update the disposed state, but their network requests continue and their promises still resolve. Disposing a controller does not clear the SDK’s shared response cache:
Deprecated v2 methods
searchFeedback() and trackingEvent() are new in v3 and have no v2 equivalent.
See Upgrade to v3 for a complete migration guide.