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 with preload hints. These cover 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
  • The SDK rewrites image URLs to use your storefront domain (derived from the request Referer header) instead of the Shopify CDN domain. This improves cache hit rates when your storefront proxies images
  • Generates responsive srcset entries at standard breakpoints (360, 540, 720, 900, 1080 pixels)

Customization

You can configure early hints behavior 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

Per-request overrides

You can override the default preload behavior on individual search and browse requests with the responseOptions.mediaPreloads body parameter. This is useful when:
  • A specific page (such as a server-rendered template or a back-office tool) does not benefit from preload hints and you want to skip the extra Link header.
  • Your client only renders specific image breakpoints and you want the emitted imagesrcset to match exactly, avoiding wasted preloads.
{
  "responseOptions": {
    "mediaPreloads": {
      "enabled": true,
      "srcsetSizes": [320, 640, 960]
    }
  }
}
Behavior:
  • enabled: false skips the Link header for this request only.
  • enabled: true cannot turn preloads on when they are disabled at the store level — store settings always take precedence.
  • srcsetSizes accepts integers between 1 and 10000. When provided, it overrides the store-level srcset configuration for this request only. Omit it to fall back to the store configuration or platform defaults.
  • When preloads are emitted, the response body’s _meta.mediaPreloads.srcsetSizes echoes the breakpoints that were used so you can verify the override took effect.
Per-request overrides are supported on the Text Search, Browse, Image Search, Similar Products, and Blocks endpoints.

Next steps

Caching

Deep dive into SDK caching behavior.

Best Practices

Review SDK best practices and common pitfalls.