Skip to main content
The Layers SDK (@commerce-blocks/sdk) is an ES module SDK for product discovery powered by Layers API. It provides reactive state management, built-in caching, and a unified interface for browse, search, recommendations, and image search.

Key Features

Layers API Integration

Full access to Layers’ search, browse, recommendations, blocks, and image search APIs with built-in error handling.

Reactive State Management

Built-in Preact Signals integration for reactive UI updates with automatic caching and request deduplication.

Product Card Controller

Reactive product card management with variant selection, availability logic, and automatic state updates.

Extensibility

Transform products, collections, and search results with custom transforms. Map filter keys for URL-friendly parameters.

Quick Start

import { createClient } from '@commerce-blocks/sdk'

const { data: client, error } = createClient({
  token: 'your-layers-token',
  sorts: [
    { name: 'Featured', code: 'featured' },
    { name: 'Price: Low to High', code: 'price_asc' },
  ],
  facets: [
    { name: 'Color', code: 'options.color' },
    { name: 'Size', code: 'options.size' },
  ],
})

if (error) {
  console.error('Client init failed:', error.message)
} else {
  const collection = client.collection({ handle: 'shirts' })
  const result = await collection.execute()
  
  if (result.data) {
    console.log(result.data.products)
  }
  
  collection.dispose()
}

Client Methods

The client provides controllers for all Layers storefront APIs:
MethodDescription
client.collection()Browse and filter products within merchandised collections
client.search()Full-text semantic search with prepare/execute flow
client.suggest()Predictive search suggestions with debouncing and local caching
client.blocks()Product recommendations powered by Layers blocks
client.uploadImage()Upload images for image-based search
client.searchByImage()Search products using uploaded images
createProductCard()Reactive product card with variant selection and availability logic

Architecture

The SDK uses a controller pattern where each method returns a controller with reactive state and execute methods. All controllers support three ways to consume state:
import { effect, subscribe } from '@commerce-blocks/sdk'

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

// 1. Controller subscribe (no signal import needed)
const unsubscribe = collection.subscribe(({ data, error, isFetching }) => {
  if (isFetching) console.log('Loading...')
  if (error) console.error('Error:', error.message)
  if (data) console.log('Products:', data.products)
})

// 2. Standalone subscribe (works with any signal)
const unsubscribe2 = subscribe(collection.state, (state) => {
  console.log('State changed:', state)
})

// 3. Direct signal access (for custom reactivity)
effect(() => {
  const { data } = collection.state.value
  if (data) console.log('Products:', data.products)
})

// Execute queries
await collection.execute() // initial load
await collection.execute({ page: 2 }) // pagination
await collection.execute({ sort: 'price_asc' }) // change sort

// Cleanup
collection.dispose()

Next Steps