Skip to main content

Overview

v2 is a ground-up redesign of the SDK. The Shopify Storefront API dependency has been removed, all controllers now expose reactive signals with built-in subscribe(), and the public API surface has been renamed and simplified. This guide covers every breaking change and provides before/after code snippets to help you migrate.

Install

npm install @commerce-blocks/sdk@^2.0.0

Initialization

The factory function and its configuration object have been renamed.
import { createSdk } from '@commerce-blocks/sdk'

const { data: sdk } = createSdk({
  token: 'your-token',
  sorts: [{ name: 'Featured', code: 'featured' }],
  facets: [{ name: 'Color', code: 'options.color' }],
  enableStorefront: true,
  storefrontApiVersion: '2024-01',
  currencyCode: 'USD',
  cacheMaxEntries: 100,
  cacheTtl: 60000,
  storageAdapter: myAdapter,
  extendProduct: ({ raw }) => ({ rating: raw.calculated?.rating ?? 0 }),
  transformFilters: (filters) => filters,
  filterMap: { color: 'options.color' },
  extendCollection: (result, raw) => result,
  extendSearch: (result, raw) => result,
  extendBlock: (result, raw) => result,
  restoreFromStorage: true,
})

Config property renames

v1v2Notes
createSdk()createClient()Factory function
currencyCodecurrency
cacheMaxEntriescacheLimit
cacheTtlcacheLifetime
storageAdapterstorage
extendProducttransforms.productMoved into transforms object
transformFilterstransforms.filtersMoved into transforms object
extendCollectiontransforms.collectionMoved into transforms object
extendSearchtransforms.searchMoved into transforms object
extendBlocktransforms.blockMoved into transforms object
filterMapfilterAliases
restoreFromStoragerestoreCache

Removed config options

These options no longer exist in v2 since the Storefront API has been removed:
  • enableStorefront
  • storefrontApiVersion
  • productMetafields / variantMetafields / collectionMetafields / pageMetafields
  • options
  • cacheMaxProducts

Storefront API removal

v2 builds products entirely from Layers API data. The Storefront API integration has been removed. What this means:
  • Remove any @shopify/storefront-api-client dependency
  • The storefront() method no longer exists on the client
  • Collection metadata (title, description, image) is now fetched via includeMeta: true on collection.execute() rather than from the Storefront API
  • Product metafields are available through the metafields property on the Product type, sourced from Layers

Controllers

All controllers now have subscribe()

Every controller in v2 exposes a subscribe() method for reacting to state changes without importing signal primitives.
const collection = client.collection({ handle: 'shirts' })

const unsubscribe = collection.subscribe(({ data, error, isFetching }) => {
  if (data) render(data.products)
})

Collection

const collection = sdk.collection({
  handle: 'shirts',
  defaultSort: 'featured',
})

await collection.execute({
  sortOrderCode: 'price_asc',
  page: 2,
  dynamicLinking: { campaign: 'summer' },
  transformBody: (body) => body,
})
v1v2
sortOrderCodesort
dynamicLinkinglinking
transformBodytransformRequest
params / paramDefinitionsRemoved — use transformRequest
Search now accepts initial options at creation time and merges parameters across execute() calls.
const search = sdk.search()

await search.execute({
  query: 'ring',
  page: 1,
  limit: 20,
  tuning: { textualWeight: 0.8 },
  dynamicLinking: { campaign: 'sale' },
})
v1v2
sdk.search() (no args)client.search(options?) accepts initial options
dynamicLinkinglinking
transformBodytransformRequest
tuning uses LayersTuningtuning uses SearchTuning
N/Atemporary flag for one-shot overrides

Autocomplete renamed to suggest

const ac = sdk.autocomplete({ debounceMs: 300 })

ac.execute(query)
// ac.state is ReadonlySignal<QueryState<PredictiveSearchResponse>>

ac.dispose()
v1v2
sdk.autocomplete()client.suggest()
debounceMsdebounce
PredictiveSearchResponseSuggestions
No subscribesuggest.subscribe()
N/AexcludeInputQuery, excludeQueries options

Blocks

const blocks = sdk.blocks({
  blockId: 'block-abc',
  anchorId: '12345',
  // or anchorHandle: 'gold-necklace'
})

await blocks.execute({
  discountEntitlements: [{ entitled: { all: true }, discount: { type: 'PERCENTAGE', value: 10 } }],
  dynamicLinking: { campaign: 'vip' },
})
v1v2
anchorId / anchorHandleanchor (single unified field)
discountEntitlementsdiscounts
dynamicLinkinglinking
const upload = sdk.uploadImage({ image: file })
// returns ReadonlySignal<QueryState<UploadImageResult>>

const results = sdk.imageSearch({ imageId: 'img-123', limit: 10 })
// returns ReadonlySignal<QueryState<SearchResult>>
v1v2
sdk.imageSearch()client.searchByImage()
Returns raw signalReturns controller with state, subscribe(), dispose()

Product type changes

v2 introduces a simplified Product type built entirely from Layers data.

Key differences

  • Shallow by default: Products include only the matched variant in variants. Enable full variants with flags: { variants: true } in createClient.
  • selectedOptions is now on the product itself (the matched variant’s options)
  • breakoutOptions replaces the previous breakout variant handling
  • options are now RichProductOption[] with code and optional swatch
  • category field added with taxonomy data
  • metafields is a nested Record<string, Record<string, unknown>> (namespace/key structure)
  • combinedListingParentProductId and combinedListingRole added for combined listings

Removed product fields

These fields from the Storefront API are no longer present:
  • descriptionHtml
  • onlineStoreUrl
  • seo
  • publishedAt
  • collections (use includeMeta on collection queries instead)

Error handling

Error types have been renamed and restructured.
import type { SdkError } from '@commerce-blocks/sdk'

if (result.error) {
  // error._tag: 'NetworkError' | 'ApiError' | 'ValidationError' | 'ConfigError'
}
v1v2
SdkErrorClientError
No retry classificationisRetryable() predicate
No retry delay inforetryAfterMs on error

Cache and store

The store module has been replaced with a flat cache API.
const { store } = sdk
// store.queries, store.collections, etc.

New in v2

These features are only available in v2:
  • searchContent controller for searching articles and blog content
  • createProductCard reactive controller for building product cards with variant selection, option availability, and pricing signals
  • subscribe() on all controllers for framework-agnostic reactivity
  • Request deduplication via the built-in RequestCoordinator
  • temporary flag on search for one-shot query overrides that don’t persist
  • prepare() on search for warming the API with a searchId before executing
  • Shallow products for significantly smaller payloads on listing pages

Type renames

v1v2
SdkClient
SdkConfigClientConfig
SdkErrorClientError
CreateSdkResultCreateClientResult
FilterMapFilterAliases
FilterMapEntryFilterAlias
FilterTransformertransforms.filters
CollectionExtendertransforms.collection
SearchExtendertransforms.search
BlocksExtendertransforms.block
CollectionExecuteQueryCollectionQuery
BlocksExecuteQueryBlocksQuery
AutocompleteOptionsSuggestOptions
AutocompleteControllerSuggestController
PredictiveSearchResponseSuggestions
PrepareSearchResultSearchPrepareResult
LayersTuningSearchTuning
BaseResultQueryResult