[{"data":1,"prerenderedAt":466},["ShallowReactive",2],{"navigation":3,"-guide-cookies":57,"-guide-cookies-surround":463},[4],{"title":5,"path":6,"stem":7,"children":8,"icon":16},"Guide","\u002Fguide","1.guide\u002F1.index",[9,12,17,22,27,32,37,42,47,52],{"title":10,"path":6,"stem":7,"icon":11},"Getting Started","lucide:rocket",{"title":13,"path":14,"stem":15,"icon":16},"API Reference","\u002Fguide\u002Fapi","1.guide\u002F10.api","lucide:book-open",{"title":18,"path":19,"stem":20,"icon":21},"Caching Functions","\u002Fguide\u002Ffunctions","1.guide\u002F2.functions","lucide:square-function",{"title":23,"path":24,"stem":25,"icon":26},"Invalidation & Expiration","\u002Fguide\u002Finvalidation","1.guide\u002F3.invalidation","lucide:trash-2",{"title":28,"path":29,"stem":30,"icon":31},"Storage","\u002Fguide\u002Fstorage","1.guide\u002F4.storage","lucide:database",{"title":33,"path":34,"stem":35,"icon":36},"Caching HTTP Handlers","\u002Fguide\u002Fhandler","1.guide\u002F5.handler","lucide:server",{"title":38,"path":39,"stem":40,"icon":41},"Query Parameters","\u002Fguide\u002Fquery-params","1.guide\u002F6.query-params","lucide:link-2",{"title":43,"path":44,"stem":45,"icon":46},"Cookies","\u002Fguide\u002Fcookies","1.guide\u002F7.cookies","lucide:cookie",{"title":48,"path":49,"stem":50,"icon":51},"Cache-Control & Eligibility","\u002Fguide\u002Fcache-control","1.guide\u002F8.cache-control","lucide:sliders-horizontal",{"title":53,"path":54,"stem":55,"icon":56},"Incremental Static Regeneration","\u002Fguide\u002Fisr","1.guide\u002F9.isr","lucide:refresh-cw",{"id":58,"title":43,"body":59,"description":101,"extension":458,"meta":459,"navigation":460,"path":44,"seo":461,"stem":45,"__hash__":462},"content\u002F1.guide\u002F7.cookies.md",{"type":60,"value":61,"toc":454,"icon":46},"minimark",[62,70,92,95,243,268,273,280,307,310,358,376,380,426,450],[63,64,65,69],"p",{},[66,67,68],"strong",{},"By default, no cookies take part in caching — in either direction."," This is a secure default:",[71,72,73,82,85],"ul",{},[74,75,76,77,81],"li",{},"The ",[78,79,80],"code",{},"Cookie"," request 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.",[74,83,84],{},"Cookies never vary the cache key.",[74,86,87,88,91],{},"Any ",[78,89,90],{},"Set-Cookie"," your handler sets is removed before the response is cached or returned.",[63,93,94],{},"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.",[96,97,102],"pre",{"className":98,"code":99,"language":100,"meta":101,"style":101},"language-ts shiki shiki-themes github-light github-dark github-dark","const page = defineCachedHandler(\n  async (event) => {\n    event.req.headers.get(\"cookie\"); \u002F\u002F always null for cached GET\u002FHEAD requests\n    return new Response(await renderPage(), {\n      headers: { \"content-type\": \"text\u002Fhtml\" },\n    });\n  },\n  { maxAge: 60 },\n);\n","ts","",[78,103,104,128,150,173,196,214,220,226,237],{"__ignoreMap":101},[105,106,109,113,117,120,124],"span",{"class":107,"line":108},"line",1,[105,110,112],{"class":111},"so5gQ","const",[105,114,116],{"class":115},"suiK_"," page",[105,118,119],{"class":111}," =",[105,121,123],{"class":122},"shcOC"," defineCachedHandler",[105,125,127],{"class":126},"slsVL","(\n",[105,129,131,134,137,141,144,147],{"class":107,"line":130},2,[105,132,133],{"class":111},"  async",[105,135,136],{"class":126}," (",[105,138,140],{"class":139},"sQHwn","event",[105,142,143],{"class":126},") ",[105,145,146],{"class":111},"=>",[105,148,149],{"class":126}," {\n",[105,151,153,156,159,162,166,169],{"class":107,"line":152},3,[105,154,155],{"class":126},"    event.req.headers.",[105,157,158],{"class":122},"get",[105,160,161],{"class":126},"(",[105,163,165],{"class":164},"sfrk1","\"cookie\"",[105,167,168],{"class":126},"); ",[105,170,172],{"class":171},"sCsY4","\u002F\u002F always null for cached GET\u002FHEAD requests\n",[105,174,176,179,182,185,187,190,193],{"class":107,"line":175},4,[105,177,178],{"class":111},"    return",[105,180,181],{"class":111}," new",[105,183,184],{"class":122}," Response",[105,186,161],{"class":126},[105,188,189],{"class":111},"await",[105,191,192],{"class":122}," renderPage",[105,194,195],{"class":126},"(), {\n",[105,197,199,202,205,208,211],{"class":107,"line":198},5,[105,200,201],{"class":126},"      headers: { ",[105,203,204],{"class":164},"\"content-type\"",[105,206,207],{"class":126},": ",[105,209,210],{"class":164},"\"text\u002Fhtml\"",[105,212,213],{"class":126}," },\n",[105,215,217],{"class":107,"line":216},6,[105,218,219],{"class":126},"    });\n",[105,221,223],{"class":107,"line":222},7,[105,224,225],{"class":126},"  },\n",[105,227,229,232,235],{"class":107,"line":228},8,[105,230,231],{"class":126},"  { maxAge: ",[105,233,234],{"class":115},"60",[105,236,213],{"class":126},[105,238,240],{"class":107,"line":239},9,[105,241,242],{"class":126},");\n",[244,245,246],"note",{},[63,247,248,249,252,253,256,257,260,261,264,265,267],{},"\nThis only applies to cacheable requests (",[78,250,251],{},"GET"," \u002F ",[78,254,255],{},"HEAD","). Methods that bypass the cache entirely (",[78,258,259],{},"POST",", ",[78,262,263],{},"PUT",", …) reach the handler with the request untouched — cookies, headers, query, and body included — and their ",[78,266,90],{}," is passed straight through.",[269,270,272],"h2",{"id":271},"allowing-specific-cookies","Allowing specific cookies",[63,274,275,276,279],{},"Set ",[78,277,278],{},"allowCookies"," to an allowlist of cookie names to opt specific cookies back in. For those cookies only:",[71,281,282,288,301],{},[74,283,284,285,287],{},"they stay in the ",[78,286,80],{}," header your handler sees,",[74,289,290,291,297,298,300],{},"they vary the cache key (sorted and order-independent, like ",[292,293,294],"a",{"href":39},[78,295,296],{},"allowQuery",", so only that subset is part of the key — not the entire raw ",[78,299,80],{}," header),",[74,302,303,304,306],{},"a matching ",[78,305,90],{}," is allowed to be cached and returned.",[63,308,309],{},"Every other cookie is still stripped in both directions, and the rest of the response is cached as usual.",[96,311,313],{"className":98,"code":312,"language":100,"meta":101,"style":101},"const page = defineCachedHandler(myHandler, {\n  maxAge: 300,\n  allowCookies: [\"theme\"], \u002F\u002F theme=dark and theme=light cache separately; every other cookie is ignored\n});\n",[78,314,315,328,339,353],{"__ignoreMap":101},[105,316,317,319,321,323,325],{"class":107,"line":108},[105,318,112],{"class":111},[105,320,116],{"class":115},[105,322,119],{"class":111},[105,324,123],{"class":122},[105,326,327],{"class":126},"(myHandler, {\n",[105,329,330,333,336],{"class":107,"line":130},[105,331,332],{"class":126},"  maxAge: ",[105,334,335],{"class":115},"300",[105,337,338],{"class":126},",\n",[105,340,341,344,347,350],{"class":107,"line":152},[105,342,343],{"class":126},"  allowCookies: [",[105,345,346],{"class":164},"\"theme\"",[105,348,349],{"class":126},"], ",[105,351,352],{"class":171},"\u002F\u002F theme=dark and theme=light cache separately; every other cookie is ignored\n",[105,354,355],{"class":107,"line":175},[105,356,357],{"class":126},"});\n",[63,359,360,361,364,365,367,368,371,372,375],{},"Cookie names are ",[66,362,363],{},"case-sensitive",". ",[78,366,278],{}," supersedes ",[78,369,370],{},"varies: [\"cookie\"]"," — set the allowlist and drop the coarse ",[78,373,374],{},"varies"," entry.",[269,377,379],{"id":378},"caveats","Caveats",[71,381,382,404],{},[74,383,384,391,392,394,395,397,398,400,401,403],{},[66,385,386,387,390],{},"Custom ",[78,388,389],{},"getKey","."," As with ",[78,393,296],{},", a custom ",[78,396,389],{}," controls the cache key entirely, so allowlisted cookies no longer vary it automatically. If your handler's output depends on a cookie, incorporate it into ",[78,399,389],{}," yourself. (The handler-visible ",[78,402,80],{}," header is still filtered to the allowlist regardless.)",[74,405,406,409,410,412,413,416,417,420,421,425],{},[66,407,408],{},"Allowlisted cookies are shared — keep them cache-safe."," An allowlisted cookie is part of the cache: its value varies the key, and its ",[78,411,90],{}," is 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 — a ",[78,414,415],{},"theme"," or ",[78,418,419],{},"locale"," preference that is genuinely ",[422,423,424],"em",{},"part of"," the key.",[427,428,429],"caution",{},[63,430,431,434,435,438,439,441,442,252,444,446,447,449],{},[66,432,433],{},"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 ",[422,436,437],{},"mints"," a per-request cookie (e.g. starting an anonymous session with a fresh ",[78,440,90],{},") must give each user a distinct entry via a user-specific ",[78,443,389],{},[78,445,374],{}," — otherwise don't cache it. With no ",[78,448,278],{},", such a cookie is simply stripped, so the default never leaks; this only matters once you opt a cookie back in.",[451,452,453],"style",{},"html pre.shiki code .so5gQ, html code.shiki .so5gQ{--shiki-light:#D73A49;--shiki-default:#F97583;--shiki-dark:#F97583}html pre.shiki code .suiK_, html code.shiki .suiK_{--shiki-light:#005CC5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .shcOC, html code.shiki .shcOC{--shiki-light:#6F42C1;--shiki-default:#B392F0;--shiki-dark:#B392F0}html pre.shiki code .slsVL, html code.shiki .slsVL{--shiki-light:#24292E;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}html pre.shiki code .sQHwn, html code.shiki .sQHwn{--shiki-light:#E36209;--shiki-default:#FFAB70;--shiki-dark:#FFAB70}html pre.shiki code .sfrk1, html code.shiki .sfrk1{--shiki-light:#032F62;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html pre.shiki code .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":101,"searchDepth":130,"depth":130,"links":455},[456,457],{"id":271,"depth":130,"text":272},{"id":378,"depth":130,"text":379},"md",{"icon":46},{"icon":46},{"title":43,"description":101},"PxEpt6xQs84qPoEecJJ5jqZtYDmNHypzZPUuYZudyHI",[464,465],{"title":38,"path":39,"stem":40,"description":101,"icon":41,"children":-1},{"title":48,"path":49,"stem":50,"description":101,"icon":51,"children":-1},1783601179227]