Skip to main content
The Layers SDK (@protonagency/sdk) is an ES module SDK for Shopify storefronts with Layers API integration. It provides reactive state management, built-in caching, and optional Shopify Storefront API enrichment for building rich commerce experiences.

Key Features

Layers API Integration

Full access to Layers’ search, browse, similar products, 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.

Shopify Enrichment

Optional Storefront API integration for richer product data including metafields, full variant info, and collection metadata.

Extensibility

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

Quick Start

import { createSdk } from '@protonagency/sdk'

const result = createSdk({
  // Layers API
  layersPublicToken: 'your-layers-token',
  sorts: [
    { label: 'Featured', code: 'featured' },
    { label: 'Price: Low to High', code: 'price_asc' },
  ],
  facets: ['options.color', 'options.size', 'vendor'],

  // Opt in to Shopify Storefront API for richer product data
  // enableStorefront: true,
  // shop: 'your-store.myshopify.com',
  // storefrontPublicToken: 'your-storefront-token',
})

if (result.error) {
  console.error('SDK init failed:', result.error.message)
} else {
  const sdk = result.data
  // Ready to use
}

SDK Methods

The SDK provides controllers for all Layers storefront APIs:
MethodDescription
sdk.collection()Browse and filter products within merchandised collections
sdk.search()Full-text semantic search with prepare/execute flow
sdk.autocomplete()Predictive search with debouncing and local caching
sdk.blocks()Product recommendations powered by Layers blocks
sdk.uploadImage()Upload images for image-based search
sdk.imageSearch()Search products using uploaded images
sdk.storefront()Fetch products by GID with optional collection/page metadata

Architecture

The SDK uses a controller pattern where each method returns a controller with reactive state and execute methods:
import { effect } from '@preact/signals-core'

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

// Subscribe to state changes
effect(() => {
  const { data, error, fetching } = collection.state.value
  if (fetching) console.log('Loading...')
  if (error) console.error('Error:', error.message)
  if (data) console.log('Products:', data.products)
})

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

// Cleanup
collection.dispose()

Next Steps