Caching
The caching functions cache Storefront API queries, third-party API responses, and other async work. Use the functions to choose how long each result stays fresh and to cache data under a key that you choose.
For Storefront API reads, use the cache option on createStorefrontClient. For other third-party requests, use createFetchWithCache. For any other async work, use createRunWithCache.
Import Cache, createFetchWithCache, and createRunWithCache from @shopify/hydrogen.
Anchor to Cache strategiesCache strategies
Anchor to cacheCache
Creates caching strategies for Storefront API queries, cached fetches, and cached runs. Call Cache with options for a custom strategy, or use the short, long, and none presets.
- Anchor to longlonglong(overrideOptions?: CacheOptions) => CachingStrategy(overrideOptions?: CacheOptions) => CachingStrategyrequiredrequired
Keeps public entries fresh for 1 hour, then serves stale entries for 23 more hours while the cache refreshes them. Pass options to override the mode or either duration, or to add
.- Anchor to nonenonenone() => NoStoreStrategy() => NoStoreStrategyrequiredrequired
Returns a strategy that skips the cache. The preset takes no options.
- Anchor to shortshortshort(overrideOptions?: CacheOptions) => CachingStrategy(overrideOptions?: CacheOptions) => CachingStrategyrequiredrequired
Keeps public entries fresh for 1 second, then serves stale entries for 9 more seconds while the cache refreshes them. Pass options to override the mode or either duration, or to add
.
CacheOptions
Options for a custom caching strategy. A duration that you leave out counts as zero seconds.
- maxAge
How long an entry stays fresh.
CacheDuration - mode
The cache mode, `public` or `private`. Defaults to `public`. Web Cache stores receive the mode in the `cache-control` header. The Storefront API client throws an error for `private`.
ExpirableCacheMode - staleIfError
How long after the stale-while-revalidate window the cache serves a stale entry when a refresh fails.
CacheDuration - staleWhileRevalidate
How long after the fresh window the cache serves a stale entry while it refreshes the entry in the background.
CacheDuration
CacheDuration
A number of seconds, or an object such as `{ minutes: 10 }`. `Cache` throws an error for a duration that isn't a finite, non-negative number, and rounds fractional totals up to whole seconds.
number | {
seconds?: number;
minutes?: number;
hours?: number;
days?: number;
}ExpirableCacheMode
The modes that a custom strategy accepts, `public` or `private`. `Cache` throws an error for any other mode.
typeof PUBLIC | typeof PRIVATECachingStrategy
A caching strategy, with every duration in whole seconds. Create a strategy with `Cache`.
- maxAge
How many seconds an entry stays fresh.
number - mode
The cache mode. A `no-store` strategy skips the cache.
CacheMode - staleIfError
How many seconds after the stale window the cache serves a stale entry when the refresh fails.
number - staleWhileRevalidate
How many seconds after the fresh window the cache serves a stale entry while it refreshes the entry in the background.
number
CacheMode
The cache mode of a strategy, `public`, `private`, or `no-store`. A `no-store` strategy skips the cache.
typeof PUBLIC | typeof PRIVATE | typeof NO_STORENoStoreStrategy
A strategy that skips the cache.
CachingStrategy & {
mode: typeof NO_STORE;
}TypeScript
Examples
Description
Opt a product list query into `Cache.long()`. This example opens a Web Cache and passes the cache to the client with `waitUntil`.
TypeScript
import { Cache, createShopifyRequestContext, createStorefrontClient, gql, } from "@shopify/hydrogen"; const PRODUCTS_QUERY = gql(`query { products(first: 10) { nodes { title } } }`); export async function getProducts(request: Request, waitUntil: (promise: Promise<unknown>) => void) { const storefront = createStorefrontClient({ type: "public", requestContext: createShopifyRequestContext({ request, i18n: { country: "US", language: "EN" } }), config: { storeDomain: process.env.PUBLIC_STORE_DOMAIN!, publicStorefrontToken: process.env.PUBLIC_STOREFRONT_API_TOKEN, cache: await caches.open("hydrogen"), waitUntil, }, }); return storefront.graphql(PRODUCTS_QUERY, { cache: Cache.long() }); }Description
Create caching strategies from durations and presets. This example builds a custom strategy, overrides a preset with `staleIfError`, and creates a no-store strategy.
TypeScript
import { Cache } from "@shopify/hydrogen"; export const tenMinutes = Cache({ maxAge: { minutes: 10 }, staleWhileRevalidate: { hours: 1 }, }); export const longWithFallback = Cache.long({ staleIfError: { minutes: 5 } }); export const noStore = Cache.none();
Anchor to Cached fetchCached fetch
Creates a fetch function that caches responses from third-party APIs. Call the function like fetch(), and pass a key and strategy in the third argument to cache the response. Calls without the third argument skip the cache. Return false from a option to skip caching one response.
The function caches only OK responses with no body or with a JSON, text, XML, HTML, GraphQL, or JavaScript content type. Other responses skip the cache. The function removes the set-cookie and server-timing headers from each cached response, including the response that a cache miss returns. With , the function serves a stale entry only after a 500, 502, 503, or 504 status, or when the fetch throws.
- Anchor to input1input1input1CreateFetchWithCacheOptionsCreateFetchWithCacheOptionsrequiredrequired
A cache, or the function from
to share its cache, plus an optional fetch function.
A fetch function that adds a
Cache-Statusheader to calls with cache options, unlessisfalse.
CreateFetchWithCacheOptions
Pass a cache and an optional `waitUntil` function, or pass `runWithCache` from `createRunWithCache` to share its cache. Set `fetch` to replace the global fetch function.
(
| CreateRunWithCacheOptions
| {
runWithCache: RunWithCache;
}
) & {
fetch?: typeof fetch;
}CreateRunWithCacheOptions
The cache and the background-work function for `createRunWithCache`.
- cache
The cache that holds entries. `createRunWithCache` throws a `TypeError` when the cache is neither a Web Cache API cache nor a key-value store.
CacheInstance - waitUntil
Keeps the runtime alive for background cache writes and refreshes. Without `waitUntil`, each call waits for its cache write before it resolves.
WaitUntil
CacheInstance
The cache that holds entries, either a Web Cache API cache or a key-value store.
WebCacheLike | KeyValueCacheLikeWebCacheLike
A cache with the `match()`, `put()`, and `delete()` methods of the Web Cache API, such as a cache from `caches.open()`.
- delete
The **`delete()`** method of the Cache interface finds the Cache entry whose key is the request, and if found, deletes the Cache entry and returns a Promise that resolves to `true`. [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache/delete)
(request: RequestInfo | URL, options?: CacheQueryOptions) => Promise<boolean> - match
The **`match()`** method of the Cache interface returns a Promise that resolves to the Response associated with the first matching request in the Cache object. [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache/match)
(request: RequestInfo | URL, options?: CacheQueryOptions) => Promise<Response> - put
The **`put()`** method of the Often, you will just want to Window/fetch one or more requests, then add the result straight to your cache. [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache/put)
(request: RequestInfo | URL, response: Response) => Promise<void>
KeyValueCacheLike
A key-value store with `get()`, `set()`, and an optional `delete()` method. Hydrogen passes each entry to `set()` as an object. Serialize the object in your store when the store saves only strings.
- delete
Removes the value under the key.
(key: string) => unknown - get
Returns the value under the key. Hydrogen treats a value that it didn't write as a cache miss.
(key: string) => unknown - set
Saves the value under the key. Expire the entry after the `ttl` option, in seconds.
(key: string, value: unknown, options?: KeyValueCacheSetOptions) => unknown
KeyValueCacheSetOptions
Options that Hydrogen passes when it writes an entry to a key-value store.
- ttl
How many seconds to keep the entry. Hydrogen passes the sum of the strategy's `maxAge`, `staleWhileRevalidate`, and `staleIfError`, rounded up.
number
WaitUntil
Keeps the runtime alive until a background cache write or refresh finishes, such as a worker's `waitUntil` function. Hydrogen ignores errors that the function throws.
- promise
The background cache write or refresh to wait for.
Promise<unknown>
Nothing. Hydrogen ignores the return value.
voidRunWithCache
Returns cached data for the key, or runs the callback and caches the result. Resolves with the data and the cache status.
- options
The cache key and caching strategy for this call.
RunWithCacheOptions - run
Produces the data and decides whether to cache it. Runs whenever the cache has no fresh entry. The context's `background` field is `true` during a stale-while-revalidate refresh.
RunCallback<T>
The data and the cache status.
interface Promise<T> {
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled The callback to execute when the Promise is resolved.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of which ever callback is executed.
*/
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;
/**
* Attaches a callback for only the rejection of the Promise.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of the callback.
*/
catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult>;
}, interface Promise<T> {}, Promise: PromiseConstructor, interface Promise<T> {
readonly [Symbol.toStringTag]: string;
}, interface Promise<T> {
/**
* Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The
* resolved value cannot be modified from the callback.
* @param onfinally The callback to execute when the Promise is settled (fulfilled or rejected).
* @returns A Promise for the completion of the callback.
*/
finally(onfinally?: (() => void) | undefined | null): Promise<T>;
}RunWithCacheOptions
Options for one cached run.
- key
Identifies the cache entry. `runWithCache` throws a `TypeError` for an array key with empty slots or with entries other than strings, numbers, booleans, and `null`.
CacheKey - strategy
Sets how long the result stays fresh, how long the cache serves it stale while refreshing it, and how long the cache serves it stale after an error.
CachingStrategy
CacheKey
Identifies a cache entry, as a string or an array of strings, numbers, booleans, and `null`. Include every value that changes the cached data.
string | readonly CacheKeyPrimitive[]CacheKeyPrimitive
One entry in an array cache key. The number `1` and the string `"1"` produce different keys.
string | number | boolean | nullRunCallback
Produces the data for a cached run and decides whether to cache the data.
- context
Tells the callback whether it refreshes a stale entry in the background.
RunWithCacheContext
The data and whether to cache the data, or a promise that resolves to both.
MaybePromise<CacheDecision<T>>RunWithCacheContext
The context that `runWithCache` passes to its callback.
- background
`true` when the callback refreshes a stale entry after the cache already returned the stale value.
boolean
MaybePromise
A value, or a promise that resolves to the value.
T | Promise<T>CacheDecision
The callback's return value, with the data and whether to cache the data.
- data
The data to return and cache. Web Cache stores save the data as JSON.
T - shouldCache
Set to `false` to return the data without storing it.
boolean
FetchWithCache
A fetch function that caches the response when you pass cache options as the third argument.
TypeScript
Examples
Description
Cache an external API response with `Cache.short()`. This example skips caching when the response body contains errors.
TypeScript
import { Cache, createFetchWithCache } from "@shopify/hydrogen"; export async function fetchReviews(productId: string, waitUntil: (promise: Promise<unknown>) => void) { const fetchWithCache = createFetchWithCache({ cache: await caches.open("reviews"), waitUntil, }); const url = `https://reviews.example.com/products/${productId}`; return fetchWithCache(url, undefined, { key: ["reviews", productId], strategy: Cache.short(), shouldCacheResponse: async ({ json }) => { const payload = await json?.().catch(() => undefined); return typeof payload === "object" && payload != null && !("errors" in payload); }, }); }
Anchor to Cached runsCached runs
Creates a function that caches the result of any async work, such as data that several API calls produce together. For a single fetch response, use .
Anchor to createRunWithCache-parametersParameters
- Anchor to input1input1input1CreateRunWithCacheOptionsCreateRunWithCacheOptionsrequiredrequired
The cache, and the function that keeps the runtime alive for background cache writes.
A function that returns cached data or runs your callback, and reports the cache status.
Returns cached data for the key, or runs the callback and caches the result.
The callback returns an object with data and a boolean . The function throws a for any other shape. During the window, the function returns the stale data right away and runs the callback in the background. During the window, the function returns the stale data when the callback throws. A no-store strategy runs the callback and skips the cache.
Anchor to runWithCache-parametersParameters
- Anchor to optionsoptionsoptionsRunWithCacheOptionsRunWithCacheOptionsrequiredrequired
The cache key and caching strategy for this call.
- Anchor to runrunrun() => MaybePromise<CacheDecision<SerializableCacheValue>>() => MaybePromise<CacheDecision<SerializableCacheValue>>requiredrequired
Produces the data and decides whether to cache it. Runs whenever the cache has no fresh entry.
The data, and whether the data came from the cache, the callback, or a bypass.
SerializableCacheValue
The plain object that you cache. Web Cache stores save the object as JSON. Return data that survives a round trip through `JSON.stringify`.
RunWithCacheResult
The data, and whether the data came from the cache or the callback.
- cacheStatus
`hit` when the data comes from the cache, `miss` when the callback runs, and `bypass` for a `no-store` strategy.
'hit' | 'miss' | 'bypass' - data
The cached data on a hit, or the callback's data otherwise.
T
TypeScript
Examples
Description
Cache an inventory summary under an array key. This example returns the cache status with the data.
TypeScript
import { Cache, createRunWithCache } from "@shopify/hydrogen"; export async function getInventorySummary( handle: string, waitUntil: (promise: Promise<unknown>) => void, ) { const runWithCache = createRunWithCache({ cache: await caches.open("inventory"), waitUntil, }); const { data, cacheStatus } = await runWithCache( { key: ["inventory-summary", handle], strategy: Cache.short() }, async () => { const response = await fetch(`https://inventory.example.com/${handle}`); if (!response.ok) { throw new Error(`Inventory request failed with ${response.status}`); } const summary: { available: number } = await response.json(); return { data: summary, shouldCache: true }; }, ); return { ...data, cacheStatus }; }
Anchor to Storefront API queriesStorefront API queries
To cache a Storefront API query, pass a cache to the Storefront API client and a Cache strategy to the query. Leave cart and customer queries without a strategy, and cache customer-specific work with createRunWithCache under a key unique to that customer.