Overview
v3 is a ground-up rewrite. The client is renamed back tosdk, controllers are stateless (params live at creation, overrides go through get()), Preact signals are gone, errors are plain Error, and facets and sort orders are fetched at runtime instead of declared at init.
This guide covers every breaking change with before/after snippets. For an end-to-end reference of the new surface, see the SDK API reference.
Install
Quick reference
Initialization
createSDK() returns { data, error } — check the error before using the SDK.
Config changes
Transforms
Endpoint transforms now receive the normalized response only — no separateraw argument. The product extender keeps its { base, raw } signature. The block key is now plural, and filters was removed.
Controllers
Stateless params
Identity params (handle, blockId, query) go at controller creation. Query params (page, sort, filters) go atget() and shallow-merge over the init values. Nothing accumulates between calls.
State access
Preact signals are gone.controller.state is a plain getter and subscribe takes the controller directly.
getState() still works as a deprecated alias for state.
QueryState shape
execute() → get()
execute() still works but is deprecated:
Per-request body transform
All controllers accepttransformBody at init to modify the request body before it is sent. This replaces v2’s per-call transformRequest.
Controller-by-controller migration
collection
search
425. prepare() is exposed for pre-warming without fetching results:
autocomplete
suggest was renamed back to autocomplete. Debounce is no longer built in — use createDebounce:
sdk.suggest({ debounce }) remains as a deprecated wrapper around autocomplete() with built-in debounce.
blocks
imageSearch
searchByImage() remains as a deprecated alias.
uploadImage
Same controller interface as v2 (state, subscribe, get, dispose). Each get() still uploads — this controller is intentionally uncached.
searchContent
typename, contentType, contentId, plus totalPages on the response.
similarProducts (new)
Find products similar to a given product by ID:facets (new)
Facets are no longer declared at init. Fetch them per query:sortOrders (new)
Sort orders are fetched at runtime:searchFeedback (new direct call)
Send search-quality feedback. Not a controller — returns a plain promise:trackingEvent (new direct call)
Send analytics events viasendBeacon with a fetch fallback:
collection_view, product_click, product_view, product_impression, product_hover, product_touch, add_to_cart, search, autocomplete, block_view.
Filter DSL
Operator renames and additions:FilterOperator enum values also changed: not_eq → neq, not_in → notIn, exists → notNull, not_exists → null. Core operators (eq, inValues, notIn, gt, gte, lt, lte, and, or, filter) are unchanged.
Filter aliases (filterAliases) are removed — build filter expressions with the DSL directly.
Error handling
The typed error hierarchy is gone. Every API returns{ data, error } with a plain Error:
ClientError, NetworkError, ApiError, ValidationError, ConfigError, isClientError, isRetryable. Internal functions no longer throw — { data, error } all the way down.
Storage
StorageAdapter was replaced with StorageBackend, which matches the standard Storage interface. Pass localStorage directly:
StorageBackend directly. localStorageAdapter() and fileStorage() are removed.
Cache
The publicclient.cache API is gone. Configure the in-memory LRU via SdkConfig:
uploadImage bypasses the cache — each get() uploads. searchFeedback and trackingEvent are not cached.