Cookies
By default, no cookies take part in caching — in either direction. This is a secure default:
- The
Cookierequest header is stripped before your handler runs, so the handler can't produce cookie-specific output that then gets cached and served to someone else. - Cookies never vary the cache key.
- Any
Set-Cookieyour handler sets is removed before the response is cached or returned.
Together these keep a per-request cookie (such as a session id) from ever reaching another visitor — whether through a later cache hit or a concurrent request that is served the same cached response.
const page = defineCachedHandler(
async (event) => {
event.req.headers.get("cookie"); // always null for cached GET/HEAD requests
return new Response(await renderPage(), {
headers: { "content-type": "text/html" },
});
},
{ maxAge: 60 },
);
This only applies to cacheable requests (
GET / HEAD). Methods that bypass the cache entirely (POST, PUT, …) reach the handler with the request untouched — cookies, headers, query, and body included — and their Set-Cookie is passed straight through.Allowing specific cookies
Set allowCookies to an allowlist of cookie names to opt specific cookies back in. For those cookies only:
- they stay in the
Cookieheader your handler sees, - they vary the cache key (sorted and order-independent, like
allowQuery, so only that subset is part of the key — not the entire rawCookieheader), - a matching
Set-Cookieis allowed to be cached and returned.
Every other cookie is still stripped in both directions, and the rest of the response is cached as usual.
const page = defineCachedHandler(myHandler, {
maxAge: 300,
allowCookies: ["theme"], // theme=dark and theme=light cache separately; every other cookie is ignored
});
Cookie names are case-sensitive. allowCookies supersedes varies: ["cookie"] — set the allowlist and drop the coarse varies entry.
Caveats
- Custom
getKey. As withallowQuery, a customgetKeycontrols the cache key entirely, so allowlisted cookies no longer vary it automatically. If your handler's output depends on a cookie, incorporate it intogetKeyyourself. (The handler-visibleCookieheader is still filtered to the allowlist regardless.) - Allowlisted cookies are shared — keep them cache-safe. An allowlisted cookie is part of the cache: its value varies the key, and its
Set-Cookieis cached and replayed to every visitor that resolves to the same key (concurrent requests are served a single shared response). Only allowlist cookies whose value is safe to share across everyone who shares that key — athemeorlocalepreference that is genuinely part of the key.
Never allowlist a per-user secret such as a session id. Because a response is shared across everyone with the same cache key, that one value would leak between users. A handler that mints a per-request cookie (e.g. starting an anonymous session with a fresh
Set-Cookie) must give each user a distinct entry via a user-specific getKey / varies — otherwise don't cache it. With no allowCookies, such a cookie is simply stripped, so the default never leaks; this only matters once you opt a cookie back in.