Skip to main content

Overview

v3 is a ground-up rewrite. The client is renamed back to sdk, 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

The package name is unchanged. Subpath exports are unchanged:

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 separate raw 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 at get() 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 accept transformBody at init to modify the request body before it is sent. This replaces v2’s per-call transformRequest.

Controller-by-controller migration

collection

Search still auto-runs prepare and retries on 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:
For an easier migration path, 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

Articles keep their v2 shape and pick up 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 via sendBeacon with a fetch fallback:
Event types: 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:
The underlying FilterOperator enum values also changed: not_eqneq, not_innotIn, existsnotNull, not_existsnull. 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:
Removed: 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:
For Node.js or SSR, implement StorageBackend directly. localStorageAdapter() and fileStorage() are removed.

Cache

The public client.cache API is gone. Configure the in-memory LRU via SdkConfig:
uploadImage bypasses the cache — each get() uploads. searchFeedback and trackingEvent are not cached.

New in v3