[{"data":1,"prerenderedAt":1425},["ShallowReactive",2],{"navigation":3,"-guide-handler":57,"-guide-handler-surround":1422},[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":33,"body":59,"description":104,"extension":1417,"meta":1418,"navigation":1419,"path":34,"seo":1420,"stem":35,"__hash__":1421},"content\u002F1.guide\u002F5.handler.md",{"type":60,"value":61,"toc":1406,"icon":36},"minimark",[62,98,368,371,384,389,447,451,472,543,552,569,635,639,645,780,790,806,810,828,974,983,987,1001,1039,1050,1054,1074,1130,1134,1137,1202,1297,1301,1321,1356,1364,1367,1402],[63,64,65,66,70,71,74,75,78,79,82,83,86,87,90,91,93,94,97],"p",{},"Wrap an HTTP handler with ",[67,68,69],"code",{},"defineCachedHandler"," to cache its ",[67,72,73],{},"Response"," automatically, complete with ",[67,76,77],{},"etag",", ",[67,80,81],{},"last-modified",", and ",[67,84,85],{},"304 Not Modified"," support. It works with any runtime that has standard ",[67,88,89],{},"Request","\u002F",[67,92,73],{}," — the event is just ",[67,95,96],{},"{ req: Request; url?: URL }",".",[99,100,105],"pre",{"className":101,"code":102,"language":103,"meta":104,"style":104},"language-ts shiki shiki-themes github-light github-dark github-dark","import { defineCachedHandler } from \"ocache\";\n\nconst handler = defineCachedHandler(\n  async (event) => {\n    const url = event.url ?? new URL(event.req.url);\n    const product = await db.getProduct(url.pathname.split(\"\u002F\").pop());\n    return Response.json(product);\n  },\n  {\n    maxAge: 300, \u002F\u002F cache fresh for 5 minutes\n    swr: true, \u002F\u002F serve stale while revalidating in the background\n    staleMaxAge: 600, \u002F\u002F ...for up to 10 minutes past expiry\n  },\n);\n\n\u002F\u002F Call it with any { req, url? } event\nconst res = await handler({ req: new Request(\"https:\u002F\u002Fexample.com\u002Fp\u002F42\") });\n","ts","",[67,106,107,130,137,157,179,205,245,260,266,272,287,301,315,320,326,331,337],{"__ignoreMap":104},[108,109,112,116,120,123,127],"span",{"class":110,"line":111},"line",1,[108,113,115],{"class":114},"so5gQ","import",[108,117,119],{"class":118},"slsVL"," { defineCachedHandler } ",[108,121,122],{"class":114},"from",[108,124,126],{"class":125},"sfrk1"," \"ocache\"",[108,128,129],{"class":118},";\n",[108,131,133],{"class":110,"line":132},2,[108,134,136],{"emptyLinePlaceholder":135},true,"\n",[108,138,140,143,147,150,154],{"class":110,"line":139},3,[108,141,142],{"class":114},"const",[108,144,146],{"class":145},"suiK_"," handler",[108,148,149],{"class":114}," =",[108,151,153],{"class":152},"shcOC"," defineCachedHandler",[108,155,156],{"class":118},"(\n",[108,158,160,163,166,170,173,176],{"class":110,"line":159},4,[108,161,162],{"class":114},"  async",[108,164,165],{"class":118}," (",[108,167,169],{"class":168},"sQHwn","event",[108,171,172],{"class":118},") ",[108,174,175],{"class":114},"=>",[108,177,178],{"class":118}," {\n",[108,180,182,185,188,190,193,196,199,202],{"class":110,"line":181},5,[108,183,184],{"class":114},"    const",[108,186,187],{"class":145}," url",[108,189,149],{"class":114},[108,191,192],{"class":118}," event.url ",[108,194,195],{"class":114},"??",[108,197,198],{"class":114}," new",[108,200,201],{"class":152}," URL",[108,203,204],{"class":118},"(event.req.url);\n",[108,206,208,210,213,215,218,221,224,227,230,233,236,239,242],{"class":110,"line":207},6,[108,209,184],{"class":114},[108,211,212],{"class":145}," product",[108,214,149],{"class":114},[108,216,217],{"class":114}," await",[108,219,220],{"class":118}," db.",[108,222,223],{"class":152},"getProduct",[108,225,226],{"class":118},"(url.pathname.",[108,228,229],{"class":152},"split",[108,231,232],{"class":118},"(",[108,234,235],{"class":125},"\"\u002F\"",[108,237,238],{"class":118},").",[108,240,241],{"class":152},"pop",[108,243,244],{"class":118},"());\n",[108,246,248,251,254,257],{"class":110,"line":247},7,[108,249,250],{"class":114},"    return",[108,252,253],{"class":118}," Response.",[108,255,256],{"class":152},"json",[108,258,259],{"class":118},"(product);\n",[108,261,263],{"class":110,"line":262},8,[108,264,265],{"class":118},"  },\n",[108,267,269],{"class":110,"line":268},9,[108,270,271],{"class":118},"  {\n",[108,273,275,278,281,283],{"class":110,"line":274},10,[108,276,277],{"class":118},"    maxAge: ",[108,279,280],{"class":145},"300",[108,282,78],{"class":118},[108,284,286],{"class":285},"sCsY4","\u002F\u002F cache fresh for 5 minutes\n",[108,288,290,293,296,298],{"class":110,"line":289},11,[108,291,292],{"class":118},"    swr: ",[108,294,295],{"class":145},"true",[108,297,78],{"class":118},[108,299,300],{"class":285},"\u002F\u002F serve stale while revalidating in the background\n",[108,302,304,307,310,312],{"class":110,"line":303},12,[108,305,306],{"class":118},"    staleMaxAge: ",[108,308,309],{"class":145},"600",[108,311,78],{"class":118},[108,313,314],{"class":285},"\u002F\u002F ...for up to 10 minutes past expiry\n",[108,316,318],{"class":110,"line":317},13,[108,319,265],{"class":118},[108,321,323],{"class":110,"line":322},14,[108,324,325],{"class":118},");\n",[108,327,329],{"class":110,"line":328},15,[108,330,136],{"emptyLinePlaceholder":135},[108,332,334],{"class":110,"line":333},16,[108,335,336],{"class":285},"\u002F\u002F Call it with any { req, url? } event\n",[108,338,340,342,345,347,349,351,354,357,360,362,365],{"class":110,"line":339},17,[108,341,142],{"class":114},[108,343,344],{"class":145}," res",[108,346,149],{"class":114},[108,348,217],{"class":114},[108,350,146],{"class":152},[108,352,353],{"class":118},"({ req: ",[108,355,356],{"class":114},"new",[108,358,359],{"class":152}," Request",[108,361,232],{"class":118},[108,363,364],{"class":125},"\"https:\u002F\u002Fexample.com\u002Fp\u002F42\"",[108,366,367],{"class":118},") });\n",[63,369,370],{},"The first request runs your handler and stores the response; subsequent requests are served from the cache until the entry expires.",[372,373,374],"note",{},[63,375,376,379,380,383],{},[67,377,378],{},"maxAge"," defaults to ",[67,381,382],{},"1"," second. Set it explicitly for anything you actually want cached.",[385,386,388],"h2",{"id":387},"what-it-does","What it does",[390,391,392,400,416,430,441],"ul",{},[393,394,395,399],"li",{},[396,397,398],"strong",{},"Cache keys"," — auto-generated from the request URL path (plus any query params and headers you opt into varying, see below).",[393,401,402,405,406,408,409,412,413,97],{},[396,403,404],{},"Conditional requests"," — answers ",[67,407,85],{}," when the client sends a matching ",[67,410,411],{},"if-none-match"," \u002F ",[67,414,415],{},"if-modified-since",[393,417,418,421,422,78,424,82,426,429],{},[396,419,420],{},"Response headers"," — synthesizes ",[67,423,77],{},[67,425,81],{},[67,427,428],{},"cache-control"," when the handler didn't set them.",[393,431,432,437,438,238],{},[396,433,434],{},[67,435,436],{},"Vary"," — advertises which request headers the response varies on (from ",[67,439,440],{},"varies",[393,442,443,446],{},[396,444,445],{},"Binary responses"," — images, tiles, and other non-text bodies are cached and replayed byte-for-byte.",[385,448,450],{"id":449},"cacheable-requests","Cacheable requests",[63,452,453,454,457,458,461,462,78,465,78,468,471],{},"Only ",[67,455,456],{},"GET"," and ",[67,459,460],{},"HEAD"," requests are cached. Every other method (",[67,463,464],{},"POST",[67,466,467],{},"PUT",[67,469,470],{},"DELETE",", ...) bypasses the cache and reaches the handler untouched.",[99,473,475],{"className":101,"code":474,"language":103,"meta":104,"style":104},"const handler = defineCachedHandler(myHandler, { maxAge: 60 });\n\nawait handler({ req: new Request(url) }); \u002F\u002F GET  → cached\nawait handler({ req: new Request(url, { method: \"POST\", body }) }); \u002F\u002F POST → runs the handler, body intact\n",[67,476,477,496,500,519],{"__ignoreMap":104},[108,478,479,481,483,485,487,490,493],{"class":110,"line":111},[108,480,142],{"class":114},[108,482,146],{"class":145},[108,484,149],{"class":114},[108,486,153],{"class":152},[108,488,489],{"class":118},"(myHandler, { maxAge: ",[108,491,492],{"class":145},"60",[108,494,495],{"class":118}," });\n",[108,497,498],{"class":110,"line":132},[108,499,136],{"emptyLinePlaceholder":135},[108,501,502,505,507,509,511,513,516],{"class":110,"line":139},[108,503,504],{"class":114},"await",[108,506,146],{"class":152},[108,508,353],{"class":118},[108,510,356],{"class":114},[108,512,359],{"class":152},[108,514,515],{"class":118},"(url) }); ",[108,517,518],{"class":285},"\u002F\u002F GET  → cached\n",[108,520,521,523,525,527,529,531,534,537,540],{"class":110,"line":159},[108,522,504],{"class":114},[108,524,146],{"class":152},[108,526,353],{"class":118},[108,528,356],{"class":114},[108,530,359],{"class":152},[108,532,533],{"class":118},"(url, { method: ",[108,535,536],{"class":125},"\"POST\"",[108,538,539],{"class":118},", body }) }); ",[108,541,542],{"class":285},"\u002F\u002F POST → runs the handler, body intact\n",[544,545,546],"important",{},[63,547,548,549,97],{},"\nA bypassed response passes through exactly as the handler returned it — no body buffering (streaming bodies survive), no synthesized cache headers, and no spurious ",[67,550,551],{},"304",[63,553,554,555,558,559,563,564,90,566,568],{},"You can bypass additional requests with ",[67,556,557],{},"shouldBypassCache",", which is ANDed on top of the built-in method check (it can only bypass ",[560,561,562],"em",{},"more"," requests, never force-cache a non-",[67,565,456],{},[67,567,460],{}," one):",[99,570,572],{"className":101,"code":571,"language":103,"meta":104,"style":104},"const handler = defineCachedHandler(myHandler, {\n  maxAge: 60,\n  \u002F\u002F Skip the cache for logged-in users\n  shouldBypassCache: (event) => event.req.headers.has(\"authorization\"),\n});\n",[67,573,574,587,597,602,630],{"__ignoreMap":104},[108,575,576,578,580,582,584],{"class":110,"line":111},[108,577,142],{"class":114},[108,579,146],{"class":145},[108,581,149],{"class":114},[108,583,153],{"class":152},[108,585,586],{"class":118},"(myHandler, {\n",[108,588,589,592,594],{"class":110,"line":132},[108,590,591],{"class":118},"  maxAge: ",[108,593,492],{"class":145},[108,595,596],{"class":118},",\n",[108,598,599],{"class":110,"line":139},[108,600,601],{"class":285},"  \u002F\u002F Skip the cache for logged-in users\n",[108,603,604,607,610,612,614,616,619,622,624,627],{"class":110,"line":159},[108,605,606],{"class":152},"  shouldBypassCache",[108,608,609],{"class":118},": (",[108,611,169],{"class":168},[108,613,172],{"class":118},[108,615,175],{"class":114},[108,617,618],{"class":118}," event.req.headers.",[108,620,621],{"class":152},"has",[108,623,232],{"class":118},[108,625,626],{"class":125},"\"authorization\"",[108,628,629],{"class":118},"),\n",[108,631,632],{"class":110,"line":181},[108,633,634],{"class":118},"});\n",[385,636,638],{"id":637},"varying-by-request-headers","Varying by request headers",[63,640,641,642,644],{},"By default the cache key depends only on the URL path — every client shares one cached entry. List header names in ",[67,643,440],{}," to cache a separate variant per header value:",[99,646,648],{"className":101,"code":647,"language":103,"meta":104,"style":104},"const handler = defineCachedHandler(\n  async (event) => {\n    const lang = event.req.headers.get(\"accept-language\") ?? \"en\";\n    return new Response(renderPage(lang), {\n      headers: { \"content-type\": \"text\u002Fhtml\" },\n    });\n  },\n  {\n    maxAge: 300,\n    varies: [\"accept-language\"], \u002F\u002F one cached entry per language\n  },\n);\n",[67,649,650,662,676,704,721,738,743,747,751,759,772,776],{"__ignoreMap":104},[108,651,652,654,656,658,660],{"class":110,"line":111},[108,653,142],{"class":114},[108,655,146],{"class":145},[108,657,149],{"class":114},[108,659,153],{"class":152},[108,661,156],{"class":118},[108,663,664,666,668,670,672,674],{"class":110,"line":132},[108,665,162],{"class":114},[108,667,165],{"class":118},[108,669,169],{"class":168},[108,671,172],{"class":118},[108,673,175],{"class":114},[108,675,178],{"class":118},[108,677,678,680,683,685,687,690,692,695,697,699,702],{"class":110,"line":139},[108,679,184],{"class":114},[108,681,682],{"class":145}," lang",[108,684,149],{"class":114},[108,686,618],{"class":118},[108,688,689],{"class":152},"get",[108,691,232],{"class":118},[108,693,694],{"class":125},"\"accept-language\"",[108,696,172],{"class":118},[108,698,195],{"class":114},[108,700,701],{"class":125}," \"en\"",[108,703,129],{"class":118},[108,705,706,708,710,713,715,718],{"class":110,"line":159},[108,707,250],{"class":114},[108,709,198],{"class":114},[108,711,712],{"class":152}," Response",[108,714,232],{"class":118},[108,716,717],{"class":152},"renderPage",[108,719,720],{"class":118},"(lang), {\n",[108,722,723,726,729,732,735],{"class":110,"line":181},[108,724,725],{"class":118},"      headers: { ",[108,727,728],{"class":125},"\"content-type\"",[108,730,731],{"class":118},": ",[108,733,734],{"class":125},"\"text\u002Fhtml\"",[108,736,737],{"class":118}," },\n",[108,739,740],{"class":110,"line":207},[108,741,742],{"class":118},"    });\n",[108,744,745],{"class":110,"line":247},[108,746,265],{"class":118},[108,748,749],{"class":110,"line":262},[108,750,271],{"class":118},[108,752,753,755,757],{"class":110,"line":268},[108,754,277],{"class":118},[108,756,280],{"class":145},[108,758,596],{"class":118},[108,760,761,764,766,769],{"class":110,"line":274},[108,762,763],{"class":118},"    varies: [",[108,765,694],{"class":125},[108,767,768],{"class":118},"], ",[108,770,771],{"class":285},"\u002F\u002F one cached entry per language\n",[108,773,774],{"class":110,"line":289},[108,775,265],{"class":118},[108,777,778],{"class":110,"line":303},[108,779,325],{"class":118},[63,781,782,783,785,786,789],{},"The same header names are also merged into the response ",[67,784,436],{}," header (case-insensitively deduped, and a handler-set ",[67,787,788],{},"Vary: *"," is left untouched) so downstream caches and CDNs store per-variant too.",[791,792,793],"tip",{},[63,794,795,801,802,805],{},[396,796,797,798,800],{},"Only headers in ",[67,799,440],{}," reach the handler."," Every other request header is stripped before the handler runs, so a handler can never accidentally produce output that depends on a header outside the cache key. (Cookies are handled separately — see ",[803,804,43],"a",{"href":44},".)",[385,807,809],{"id":808},"conditional-requests-304","Conditional requests & 304",[63,811,812,813,815,816,818,819,821,822,824,825,827],{},"When a client re-requests with ",[67,814,411],{}," (matching the stored ",[67,817,77],{},") or ",[67,820,415],{}," (at or after ",[67,823,81],{},"), the handler returns ",[67,826,85],{}," with an empty body:",[99,829,831],{"className":101,"code":830,"language":103,"meta":104,"style":104},"const handler = defineCachedHandler(() => new Response(\"\u003Ch1>Hi\u003C\u002Fh1>\"), {\n  maxAge: 300,\n});\n\nconst first = await handler({ req: new Request(url) });\nconst etag = first.headers.get(\"etag\");\n\n\u002F\u002F Browser revalidates with the etag it received\nconst second = await handler({\n  req: new Request(url, { headers: { \"if-none-match\": etag } }),\n});\nsecond.status; \u002F\u002F 304\n",[67,832,833,860,868,872,876,898,919,923,928,944,962,966],{"__ignoreMap":104},[108,834,835,837,839,841,843,846,848,850,852,854,857],{"class":110,"line":111},[108,836,142],{"class":114},[108,838,146],{"class":145},[108,840,149],{"class":114},[108,842,153],{"class":152},[108,844,845],{"class":118},"(() ",[108,847,175],{"class":114},[108,849,198],{"class":114},[108,851,712],{"class":152},[108,853,232],{"class":118},[108,855,856],{"class":125},"\"\u003Ch1>Hi\u003C\u002Fh1>\"",[108,858,859],{"class":118},"), {\n",[108,861,862,864,866],{"class":110,"line":132},[108,863,591],{"class":118},[108,865,280],{"class":145},[108,867,596],{"class":118},[108,869,870],{"class":110,"line":139},[108,871,634],{"class":118},[108,873,874],{"class":110,"line":159},[108,875,136],{"emptyLinePlaceholder":135},[108,877,878,880,883,885,887,889,891,893,895],{"class":110,"line":181},[108,879,142],{"class":114},[108,881,882],{"class":145}," first",[108,884,149],{"class":114},[108,886,217],{"class":114},[108,888,146],{"class":152},[108,890,353],{"class":118},[108,892,356],{"class":114},[108,894,359],{"class":152},[108,896,897],{"class":118},"(url) });\n",[108,899,900,902,905,907,910,912,914,917],{"class":110,"line":207},[108,901,142],{"class":114},[108,903,904],{"class":145}," etag",[108,906,149],{"class":114},[108,908,909],{"class":118}," first.headers.",[108,911,689],{"class":152},[108,913,232],{"class":118},[108,915,916],{"class":125},"\"etag\"",[108,918,325],{"class":118},[108,920,921],{"class":110,"line":247},[108,922,136],{"emptyLinePlaceholder":135},[108,924,925],{"class":110,"line":262},[108,926,927],{"class":285},"\u002F\u002F Browser revalidates with the etag it received\n",[108,929,930,932,935,937,939,941],{"class":110,"line":268},[108,931,142],{"class":114},[108,933,934],{"class":145}," second",[108,936,149],{"class":114},[108,938,217],{"class":114},[108,940,146],{"class":152},[108,942,943],{"class":118},"({\n",[108,945,946,949,951,953,956,959],{"class":110,"line":274},[108,947,948],{"class":118},"  req: ",[108,950,356],{"class":114},[108,952,359],{"class":152},[108,954,955],{"class":118},"(url, { headers: { ",[108,957,958],{"class":125},"\"if-none-match\"",[108,960,961],{"class":118},": etag } }),\n",[108,963,964],{"class":110,"line":289},[108,965,634],{"class":118},[108,967,968,971],{"class":110,"line":303},[108,969,970],{"class":118},"second.status; ",[108,972,973],{"class":285},"\u002F\u002F 304\n",[63,975,976,977,979,980,982],{},"The ",[67,978,551],{}," echoes the ",[67,981,436],{}," header so downstream caches keep the variant dimension.",[385,984,986],{"id":985},"headers-only-mode","Headers-only mode",[63,988,989,990,993,994,997,998,1000],{},"Set ",[67,991,992],{},"headersOnly: true"," to answer conditional requests ",[396,995,996],{},"without"," caching the response body. On a conditional match the handler short-circuits with a ",[67,999,551],{},"; otherwise your handler runs and its response is returned as-is (never stored):",[99,1002,1004],{"className":101,"code":1003,"language":103,"meta":104,"style":104},"const handler = defineCachedHandler(myHandler, {\n  headersOnly: true,\n  maxAge: 60,\n});\n",[67,1005,1006,1018,1027,1035],{"__ignoreMap":104},[108,1007,1008,1010,1012,1014,1016],{"class":110,"line":111},[108,1009,142],{"class":114},[108,1011,146],{"class":145},[108,1013,149],{"class":114},[108,1015,153],{"class":152},[108,1017,586],{"class":118},[108,1019,1020,1023,1025],{"class":110,"line":132},[108,1021,1022],{"class":118},"  headersOnly: ",[108,1024,295],{"class":145},[108,1026,596],{"class":118},[108,1028,1029,1031,1033],{"class":110,"line":139},[108,1030,591],{"class":118},[108,1032,492],{"class":145},[108,1034,596],{"class":118},[108,1036,1037],{"class":110,"line":159},[108,1038,634],{"class":118},[63,1040,1041,1042,90,1044,1046,1047,1049],{},"Use this when the handler already produces its own ",[67,1043,77],{},[67,1045,81],{}," and you only want the ",[67,1048,551],{}," shortcut, not full response storage.",[385,1051,1053],{"id":1052},"cache-status-header","Cache-status header",[63,1055,1056,1057,1060,1061,78,1064,78,1067,1070,1071,97],{},"By default a CDN-style ",[67,1058,1059],{},"X-Cache"," header is added, reporting how the response was served: ",[67,1062,1063],{},"MISS",[67,1065,1066],{},"HIT",[67,1068,1069],{},"STALE",", or ",[67,1072,1073],{},"REVALIDATED",[99,1075,1077],{"className":101,"code":1076,"language":103,"meta":104,"style":104},"defineCachedHandler(myHandler, { maxAge: 60 }); \u002F\u002F adds X-Cache\ndefineCachedHandler(myHandler, { maxAge: 60, cacheStatusHeader: \"x-my-cache\" }); \u002F\u002F custom name\ndefineCachedHandler(myHandler, { maxAge: 60, cacheStatusHeader: false }); \u002F\u002F disable\n",[67,1078,1079,1093,1112],{"__ignoreMap":104},[108,1080,1081,1083,1085,1087,1090],{"class":110,"line":111},[108,1082,69],{"class":152},[108,1084,489],{"class":118},[108,1086,492],{"class":145},[108,1088,1089],{"class":118}," }); ",[108,1091,1092],{"class":285},"\u002F\u002F adds X-Cache\n",[108,1094,1095,1097,1099,1101,1104,1107,1109],{"class":110,"line":132},[108,1096,69],{"class":152},[108,1098,489],{"class":118},[108,1100,492],{"class":145},[108,1102,1103],{"class":118},", cacheStatusHeader: ",[108,1105,1106],{"class":125},"\"x-my-cache\"",[108,1108,1089],{"class":118},[108,1110,1111],{"class":285},"\u002F\u002F custom name\n",[108,1113,1114,1116,1118,1120,1122,1125,1127],{"class":110,"line":139},[108,1115,69],{"class":152},[108,1117,489],{"class":118},[108,1119,492],{"class":145},[108,1121,1103],{"class":118},[108,1123,1124],{"class":145},"false",[108,1126,1089],{"class":118},[108,1128,1129],{"class":285},"\u002F\u002F disable\n",[385,1131,1133],{"id":1132},"framework-integration-hooks","Framework integration hooks",[63,1135,1136],{},"To adapt to a specific framework's request\u002Fresponse types, override any of these:",[390,1138,1139,1154,1185],{},[393,1140,1141,1144,1145,1147,1148,1150,1151,97],{},[67,1142,1143],{},"toResponse(value, event)"," — convert the handler's return value into a ",[67,1146,73],{},". Default: return it as-is if it's already a ",[67,1149,73],{},", otherwise ",[67,1152,1153],{},"new Response(String(value))",[393,1155,1156,1159,1160,1162,1163,1166,1167,1170,1171,1174,1175,1178,1179,1181,1182,97],{},[67,1157,1158],{},"createResponse(body, init)"," — build the final ",[67,1161,73],{}," served from the cache. ",[67,1164,1165],{},"body"," is a ",[67,1168,1169],{},"string"," (text), a ",[67,1172,1173],{},"Uint8Array"," (binary), or ",[67,1176,1177],{},"null"," (empty \u002F ",[67,1180,551],{},"). Default: ",[67,1183,1184],{},"new Response(body, init)",[393,1186,1187,1190,1191,1193,1194,1196,1197,412,1199,1201],{},[67,1188,1189],{},"handleCacheHeaders(event, conditions)"," — decide whether to answer with a ",[67,1192,551],{},". Return ",[67,1195,295],{}," to short-circuit. Default: the built-in ",[67,1198,411],{},[67,1200,415],{}," check.",[99,1203,1205],{"className":101,"code":1204,"language":103,"meta":104,"style":104},"const handler = defineCachedHandler(\n  \u002F\u002F Handler returns a plain object...\n  async (event) => ({ id: 42, name: \"Widget\" }),\n  {\n    maxAge: 300,\n    \u002F\u002F ...toResponse turns it into JSON\n    toResponse: (value) => Response.json(value),\n  },\n);\n",[67,1206,1207,1219,1224,1251,1255,1263,1268,1289,1293],{"__ignoreMap":104},[108,1208,1209,1211,1213,1215,1217],{"class":110,"line":111},[108,1210,142],{"class":114},[108,1212,146],{"class":145},[108,1214,149],{"class":114},[108,1216,153],{"class":152},[108,1218,156],{"class":118},[108,1220,1221],{"class":110,"line":132},[108,1222,1223],{"class":285},"  \u002F\u002F Handler returns a plain object...\n",[108,1225,1226,1228,1230,1232,1234,1236,1239,1242,1245,1248],{"class":110,"line":139},[108,1227,162],{"class":114},[108,1229,165],{"class":118},[108,1231,169],{"class":168},[108,1233,172],{"class":118},[108,1235,175],{"class":114},[108,1237,1238],{"class":118}," ({ id: ",[108,1240,1241],{"class":145},"42",[108,1243,1244],{"class":118},", name: ",[108,1246,1247],{"class":125},"\"Widget\"",[108,1249,1250],{"class":118}," }),\n",[108,1252,1253],{"class":110,"line":159},[108,1254,271],{"class":118},[108,1256,1257,1259,1261],{"class":110,"line":181},[108,1258,277],{"class":118},[108,1260,280],{"class":145},[108,1262,596],{"class":118},[108,1264,1265],{"class":110,"line":207},[108,1266,1267],{"class":285},"    \u002F\u002F ...toResponse turns it into JSON\n",[108,1269,1270,1273,1275,1278,1280,1282,1284,1286],{"class":110,"line":247},[108,1271,1272],{"class":152},"    toResponse",[108,1274,609],{"class":118},[108,1276,1277],{"class":168},"value",[108,1279,172],{"class":118},[108,1281,175],{"class":114},[108,1283,253],{"class":118},[108,1285,256],{"class":152},[108,1287,1288],{"class":118},"(value),\n",[108,1290,1291],{"class":110,"line":262},[108,1292,265],{"class":118},[108,1294,1295],{"class":110,"line":268},[108,1296,325],{"class":118},[385,1298,1300],{"id":1299},"on-demand-revalidation","On-demand revalidation",[63,1302,1303,1304,78,1307,82,1310,1313,1314,1317,1318,1320],{},"The returned handler carries ",[67,1305,1306],{},".expire(event)",[67,1308,1309],{},".invalidate(event)",[67,1311,1312],{},".resolveKeys(event)",", mirroring the methods on a ",[803,1315,1316],{"href":24},"cached function",". Each takes the request ",[67,1319,169],{}," and derives the exact key the handler cached it under:",[99,1322,1324],{"className":101,"code":1323,"language":103,"meta":104,"style":104},"await page.expire(event); \u002F\u002F mark stale — serve stale once more, refresh in background (SWR)\nawait page.invalidate(event); \u002F\u002F remove — next request blocks on a fresh render\n",[67,1325,1326,1342],{"__ignoreMap":104},[108,1327,1328,1330,1333,1336,1339],{"class":110,"line":111},[108,1329,504],{"class":114},[108,1331,1332],{"class":118}," page.",[108,1334,1335],{"class":152},"expire",[108,1337,1338],{"class":118},"(event); ",[108,1340,1341],{"class":285},"\u002F\u002F mark stale — serve stale once more, refresh in background (SWR)\n",[108,1343,1344,1346,1348,1351,1353],{"class":110,"line":132},[108,1345,504],{"class":114},[108,1347,1332],{"class":118},[108,1349,1350],{"class":152},"invalidate",[108,1352,1338],{"class":118},[108,1354,1355],{"class":285},"\u002F\u002F remove — next request blocks on a fresh render\n",[63,1357,1358,1359,1363],{},"See ",[803,1360,1362],{"href":1361},"\u002Fguide\u002Fisr#on-demand-revalidation","ISR → on-demand revalidation"," for the full recipe.",[385,1365,1366],{"id":562},"More",[390,1368,1369,1374,1379,1396],{},[393,1370,1371,1373],{},[803,1372,38],{"href":39}," — control which params vary the cache.",[393,1375,1376,1378],{},[803,1377,43],{"href":44}," — the secure default and how to opt cookies back in.",[393,1380,1381,1383,1384,90,1387,78,1390,78,1393,97],{},[803,1382,48],{"href":49}," — ",[67,1385,1386],{},"no-store",[67,1388,1389],{},"private",[67,1391,1392],{},"sendCacheControl",[67,1394,1395],{},"shouldCache",[393,1397,1398,1401],{},[803,1399,1400],{"href":54},"Incremental Static Regeneration (ISR)"," — serve stale, revalidate in the background.",[1403,1404,1405],"style",{},"html pre.shiki code .so5gQ, html code.shiki .so5gQ{--shiki-light:#D73A49;--shiki-default:#F97583;--shiki-dark:#F97583}html pre.shiki code .slsVL, html code.shiki .slsVL{--shiki-light:#24292E;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}html pre.shiki code .sfrk1, html code.shiki .sfrk1{--shiki-light:#032F62;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}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 .sQHwn, html code.shiki .sQHwn{--shiki-light:#E36209;--shiki-default:#FFAB70;--shiki-dark:#FFAB70}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":104,"searchDepth":132,"depth":132,"links":1407},[1408,1409,1410,1411,1412,1413,1414,1415,1416],{"id":387,"depth":132,"text":388},{"id":449,"depth":132,"text":450},{"id":637,"depth":132,"text":638},{"id":808,"depth":132,"text":809},{"id":985,"depth":132,"text":986},{"id":1052,"depth":132,"text":1053},{"id":1132,"depth":132,"text":1133},{"id":1299,"depth":132,"text":1300},{"id":562,"depth":132,"text":1366},"md",{"icon":36},{"icon":36},{"title":33,"description":104},"nW4_-b3pI-kBSJbazr0kNq0Bomoy2Z-JNiPKF77H104",[1423,1424],{"title":28,"path":29,"stem":30,"description":104,"icon":31,"children":-1},{"title":38,"path":39,"stem":40,"description":104,"icon":41,"children":-1},1783601179226]