Query Parameters
By default the full query string is part of the cache key, so ?color=red and ?color=red&utm=x are cached as separate entries. That means unrelated params — tracking tags, cache-busters — fragment your cache and lower the hit rate.
Set allowQuery to an allowlist of param names so only those vary the key; every other param is ignored:
const handler = defineCachedHandler(
async (event) => {
const url = event.url ?? new URL(event.req.url);
const color = url.searchParams.get("color") ?? "default";
return new Response(renderSwatch(color), {
headers: { "content-type": "text/html" },
});
},
{
maxAge: 300,
allowQuery: ["color"],
},
);
// All of these share ONE cached entry (only `color` matters):
await handler({ req: new Request("https://shop.dev/swatch?color=red") });
await handler({ req: new Request("https://shop.dev/swatch?color=red&lang=en") });
await handler({ req: new Request("https://shop.dev/swatch?color=red&utm=ig") });
Matching is order-independent and normalized: ?color=red&size=l and ?size=l&color=red hit the same entry, and repeated (array) params like ?color=red&color=blue are matched regardless of order.
Ignored params never reach the handler. Just like non-
varies headers, params outside the allowlist are stripped from the URL the handler receives — so a handler can never accidentally produce output that depends on a param outside the cache key.Edge cases
- Cache everything under one key. An empty allowlist (
allowQuery: []) drops the whole query string, so every request to the path shares a single entry (and the handler always sees a query-less URL). - Case-sensitive.
allowQuery: ["color"]does not match?Color=red.
getKey overrides the key entirely. If you provide a custom getKey, it — not allowQuery — decides the cache key. allowQuery no longer influences the key, but non-allowlisted params are still stripped from the URL the handler sees.defineCachedHandler(myHandler, {
maxAge: 300,
allowQuery: ["color"], // still strips other params from the handler's URL
getKey: (event) => new URL(event.req.url).pathname, // but this defines the key
});