Skip to main content

Concurrent requests

Execute independent requests in parallel:
// ❌ Slow - sequential
const searchResult = await client.search({ query: 'ring' }).execute()
const collectionResult = await client.collection({ handle: 'featured' }).execute()

// ✅ Fast - parallel
const [searchResult, collectionResult] = await Promise.all([
  client.search({ query: 'ring' }).execute(),
  client.collection({ handle: 'featured' }).execute(),
])
Call prepare and autocomplete concurrently for search-as-you-type:
const search = client.search()
const suggest = client.suggest()

await Promise.all([
  search.prepare({ query: 'ring' }),
  suggest.execute('ring'),
])

Prefetch next page

Prefetch the next page while the customer views the current page:
const collection = client.collection({ handle: 'shirts' })

// Load current page
const page1 = await collection.execute({ page: 1 })

// Prefetch next page in background
collection.execute({ page: 2 })

Request only needed attributes

Reduce response size by requesting only required attributes:
// Configure attributes at client init time
const { data: client } = createClient({
  token: 'your-token',
  sorts: [{ name: 'Featured', code: 'featured' }],
  facets: [{ name: 'Color', code: 'options.color' }],
  attributes: ['price_range', 'body_html'], // additional attributes beyond defaults
})

Debouncing

The SDK handles debouncing automatically, but you can tune it:
// Faster response (more API calls)
const suggest = client.suggest({ debounce: 150 })

// Slower response (fewer API calls)
const suggest = client.suggest({ debounce: 500 })

Warm cache on page load

Preload common queries on page load:
Promise.all([
  client.search({ query: 'ring' }).prepare(),
  client.collection({ handle: 'featured' }).execute(),
])
Layers API responses automatically include HTTP Link headers with rel="preload" directives for product images in search and browse results. These headers enable browsers and CDNs to begin fetching images before your application processes the JSON response, reducing perceived load time.

How it works

When a search or browse request returns results, the response includes a Link header containing preload hints for the featured_media images of the first results (up to 6 items). Each hint includes a responsive imagesrcset with multiple sizes so the browser can select the optimal resolution. Example response header:
Link: <https://yourstore.com/cdn/shop/files/product.jpg>; rel="preload"; fetchpriority="high"; as="image"; imagesrcset="https://yourstore.com/cdn/shop/files/product.jpg?width=360 360w, https://yourstore.com/cdn/shop/files/product.jpg?width=540 540w, https://yourstore.com/cdn/shop/files/product.jpg?width=720 720w"; type="image/jpeg"

Default behavior

  • Enabled by default for all stores
  • Covers the first 6 product images in the response
  • Image URLs are rewritten to use your storefront domain (derived from the request Referer header) instead of the Shopify CDN domain, which improves cache hit rates when your storefront proxies images
  • Generates responsive srcset entries at standard breakpoints (360, 540, 720, 900, 1080 pixels)

Customization

Early hints behavior can be configured per store through the Layers dashboard. Available options include:
OptionDescriptionDefault
EnabledToggle early hints on or offtrue
Srcset sizesCustom responsive image widths (in pixels)Platform defaults
Rewrite domainA specific domain to use for image URLs instead of the referrer domainReferrer domain
Rewrite URLsWhether to rewrite Shopify CDN URLs to your storefront domaintrue

Next steps

Caching

Deep dive into SDK caching behavior.

Best Practices

Review SDK best practices and common pitfalls.