[{"data":1,"prerenderedAt":1867},["ShallowReactive",2],{"navigation":3,"-docs-cache":224,"-docs-cache-surround":1862},[4,83,208,214,221],{"title":5,"path":6,"stem":7,"children":8,"icon":82},"","/docs","1.docs/1.index",[9,12,17,22,27,32,37,42,47,52,57,62,67,72,77],{"title":10,"path":6,"stem":7,"icon":11},"Introduction","i-lucide-compass",{"title":13,"path":14,"stem":15,"icon":16},"Quick Start","/docs/quick-start","1.docs/2.quick-start","i-lucide-zap",{"title":18,"path":19,"stem":20,"icon":21},"Renderer","/docs/renderer","1.docs/4.renderer","ri:layout-masonry-line",{"title":23,"path":24,"stem":25,"icon":26},"Routing","/docs/routing","1.docs/5.routing","ri:direction-line",{"title":28,"path":29,"stem":30,"icon":31},"Assets","/docs/assets","1.docs/50.assets","ri:image-2-line",{"title":33,"path":34,"stem":35,"icon":36},"Configuration","/docs/configuration","1.docs/50.configuration","ri:settings-3-line",{"title":38,"path":39,"stem":40,"icon":41},"Database","/docs/database","1.docs/50.database","ri:database-2-line",{"title":43,"path":44,"stem":45,"icon":46},"Lifecycle","/docs/lifecycle","1.docs/50.lifecycle","i-lucide-layers",{"title":48,"path":49,"stem":50,"icon":51},"Plugins","/docs/plugins","1.docs/50.plugins","ri:plug-line",{"title":53,"path":54,"stem":55,"icon":56},"Tasks","/docs/tasks","1.docs/50.tasks","codicon:run-all",{"title":58,"path":59,"stem":60,"icon":61},"Server Entry","/docs/server-entry","1.docs/6.server-entry","ri:server-line",{"title":63,"path":64,"stem":65,"icon":66},"Cache","/docs/cache","1.docs/7.cache","ri:speed-line",{"title":68,"path":69,"stem":70,"icon":71},"KV Storage","/docs/storage","1.docs/8.storage","carbon:datastore",{"title":73,"path":74,"stem":75,"icon":76},"Migration Guide","/docs/migration","1.docs/99.migration","ri:arrow-right-up-line",{"title":78,"path":79,"stem":80,"icon":81},"Nightly Channel","/docs/nightly","1.docs/99.nightly","ri:moon-fill","i-lucide-book-open",{"title":84,"path":85,"stem":86,"children":87,"icon":89},"Deploy","/deploy","2.deploy/0.index",[88,90,111],{"title":84,"path":85,"stem":86,"icon":89},"ri:upload-cloud-2-line",{"title":91,"path":92,"stem":93,"children":94,"page":110},"Runtimes","/deploy/runtimes","2.deploy/10.runtimes",[95,100,105],{"title":96,"path":97,"stem":98,"icon":99},"Node.js","/deploy/runtimes/node","2.deploy/10.runtimes/1.node","akar-icons:node-fill",{"title":101,"path":102,"stem":103,"icon":104},"Bun","/deploy/runtimes/bun","2.deploy/10.runtimes/bun","simple-icons:bun",{"title":106,"path":107,"stem":108,"icon":109},"Deno","/deploy/runtimes/deno","2.deploy/10.runtimes/deno","simple-icons:deno",false,{"title":112,"path":113,"stem":114,"children":115,"page":110},"Providers","/deploy/providers","2.deploy/20.providers",[116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188,192,196,200,204],{"title":117,"path":118,"stem":119},"Alwaysdata","/deploy/providers/alwaysdata","2.deploy/20.providers/alwaysdata",{"title":121,"path":122,"stem":123},"AWS Lambda","/deploy/providers/aws","2.deploy/20.providers/aws",{"title":125,"path":126,"stem":127},"AWS Amplify","/deploy/providers/aws-amplify","2.deploy/20.providers/aws-amplify",{"title":129,"path":130,"stem":131},"Azure","/deploy/providers/azure","2.deploy/20.providers/azure",{"title":133,"path":134,"stem":135},"Cleavr","/deploy/providers/cleavr","2.deploy/20.providers/cleavr",{"title":137,"path":138,"stem":139},"Cloudflare","/deploy/providers/cloudflare","2.deploy/20.providers/cloudflare",{"title":141,"path":142,"stem":143},"Deno Deploy","/deploy/providers/deno-deploy","2.deploy/20.providers/deno-deploy",{"title":145,"path":146,"stem":147},"DigitalOcean","/deploy/providers/digitalocean","2.deploy/20.providers/digitalocean",{"title":149,"path":150,"stem":151},"Firebase","/deploy/providers/firebase","2.deploy/20.providers/firebase",{"title":153,"path":154,"stem":155},"Flightcontrol","/deploy/providers/flightcontrol","2.deploy/20.providers/flightcontrol",{"title":157,"path":158,"stem":159},"Genezio","/deploy/providers/genezio","2.deploy/20.providers/genezio",{"title":161,"path":162,"stem":163},"GitHub Pages","/deploy/providers/github-pages","2.deploy/20.providers/github-pages",{"title":165,"path":166,"stem":167},"GitLab Pages","/deploy/providers/gitlab-pages","2.deploy/20.providers/gitlab-pages",{"title":169,"path":170,"stem":171},"Heroku","/deploy/providers/heroku","2.deploy/20.providers/heroku",{"title":173,"path":174,"stem":175},"IIS","/deploy/providers/iis","2.deploy/20.providers/iis",{"title":177,"path":178,"stem":179},"Koyeb","/deploy/providers/koyeb","2.deploy/20.providers/koyeb",{"title":181,"path":182,"stem":183},"Netlify","/deploy/providers/netlify","2.deploy/20.providers/netlify",{"title":185,"path":186,"stem":187},"Platform.sh","/deploy/providers/platform-sh","2.deploy/20.providers/platform-sh",{"title":189,"path":190,"stem":191},"Render.com","/deploy/providers/render","2.deploy/20.providers/render",{"title":193,"path":194,"stem":195},"StormKit","/deploy/providers/stormkit","2.deploy/20.providers/stormkit",{"title":197,"path":198,"stem":199},"Vercel","/deploy/providers/vercel","2.deploy/20.providers/vercel",{"title":201,"path":202,"stem":203},"Zeabur","/deploy/providers/zeabur","2.deploy/20.providers/zeabur",{"title":205,"path":206,"stem":207},"Zerops","/deploy/providers/zerops","2.deploy/20.providers/zerops",{"title":209,"path":210,"stem":211,"children":212,"icon":36},"Config","/config","3.config/0.index",[213],{"title":209,"path":210,"stem":211,"icon":36},{"title":215,"path":216,"stem":217,"children":218,"icon":220},"Examples","/examples","4.examples/0.index",[219],{"title":215,"path":216,"stem":217,"icon":220},"i-lucide-folder-code",{"title":5,"path":222,"stem":223},"/","index",{"id":225,"title":63,"body":226,"description":1856,"extension":1857,"meta":1858,"navigation":1859,"path":64,"seo":1860,"stem":65,"__hash__":1861},"content/1.docs/7.cache.md",{"type":227,"value":228,"toc":1848,"icon":66},"minimark",[229,236,241,249,262,360,366,373,390,394,401,404,704,715,768,773,1052,1056,1059,1066,1133,1145,1246,1250,1257,1283,1293,1363,1369,1447,1450,1459,1605,1609,1618,1666,1669,1761,1764,1787,1790,1838,1844],[230,231,232],"warning",{},[233,234,235],"p",{},"Nitro v3 Alpha docs are a work in progress — expect updates, rough edges, and occasional inaccuracies.",[237,238,240],"h2",{"id":239},"cached-handlers","Cached handlers",[233,242,243,244,248],{},"To cache an event handler, you simply need to use the ",[245,246,247],"code",{},"defineCachedHandler"," method.",[233,250,251,252,255,256,261],{},"It works like ",[245,253,254],{},"defineHandler"," but with an second parameter for the ",[257,258,260],"a",{"href":259},"#options","cache options",".",[263,264,269],"pre",{"className":265,"code":266,"filename":267,"language":268,"meta":5,"style":5},"language-ts shiki shiki-themes github-light github-dark github-dark","import { defineCachedHandler } from \"nitro/cache\";\n\nexport default defineCachedHandler((event) => {\n  return \"I am cached for an hour\";\n}, { maxAge: 60 * 60 });\n","routes/cached.ts","ts",[245,270,271,294,301,330,341],{"__ignoreMap":5},[272,273,276,280,284,287,291],"span",{"class":274,"line":275},"line",1,[272,277,279],{"class":278},"so5gQ","import",[272,281,283],{"class":282},"slsVL"," { defineCachedHandler } ",[272,285,286],{"class":278},"from",[272,288,290],{"class":289},"sfrk1"," \"nitro/cache\"",[272,292,293],{"class":282},";\n",[272,295,297],{"class":274,"line":296},2,[272,298,300],{"emptyLinePlaceholder":299},true,"\n",[272,302,304,307,310,314,317,321,324,327],{"class":274,"line":303},3,[272,305,306],{"class":278},"export",[272,308,309],{"class":278}," default",[272,311,313],{"class":312},"shcOC"," defineCachedHandler",[272,315,316],{"class":282},"((",[272,318,320],{"class":319},"sQHwn","event",[272,322,323],{"class":282},") ",[272,325,326],{"class":278},"=>",[272,328,329],{"class":282}," {\n",[272,331,333,336,339],{"class":274,"line":332},4,[272,334,335],{"class":278},"  return",[272,337,338],{"class":289}," \"I am cached for an hour\"",[272,340,293],{"class":282},[272,342,344,347,351,354,357],{"class":274,"line":343},5,[272,345,346],{"class":282},"}, { maxAge: ",[272,348,350],{"class":349},"suiK_","60",[272,352,353],{"class":278}," *",[272,355,356],{"class":349}," 60",[272,358,359],{"class":282}," });\n",[233,361,362,363,261],{},"With this example, the response will be cached for 1 hour and a stale value will be sent to the client while the cache is being updated in the background. If you want to immediately return the updated response set ",[245,364,365],{},"swr: false",[233,367,368,369,372],{},"See the ",[257,370,371],{"href":259},"options"," section for more details about the available options.",[374,375,376],"important",{},[233,377,378,382,383,389],{},[379,380,381],"strong",{},"Request headers are dropped"," when handling cached responses. Use the ",[257,384,385,388],{"href":259},[245,386,387],{},"varies"," option"," to consider specific headers when caching and serving the responses.",[237,391,393],{"id":392},"cached-functions","Cached functions",[233,395,396,397,400],{},"You can also cache a function using the ",[245,398,399],{},"defineCachedFunction"," function. This is useful for caching the result of a function that is not an event handler, but is part of one, and reusing it in multiple handlers.",[233,402,403],{},"For example, you might want to cache the result of an API call for one hour:",[263,405,408],{"className":265,"code":406,"filename":407,"language":268,"meta":5,"style":5},"import { defineHandler, type H3Event } from \"nitro/h3\";\nimport { defineHandler, defineCachedFunction } from \"nitro/cache\";\n\nexport default defineHandler(async (event) => {\n  const { repo } = event.context.params;\n  const stars = await cachedGHStars(repo).catch(() => 0)\n\n  return { repo, stars }\n});\n\nconst cachedGHStars = defineCachedFunction(async (repo: string) => {\n  const data = await fetch(`https://api.github.com/repos/${repo}`).then(res => res.json());\n\n  return data.stargazers_count;\n}, {\n  maxAge: 60 * 60,\n  name: \"ghStars\",\n  getKey: (repo: string) => repo\n});\n","routes/api/stars/[...repo].ts",[245,409,410,430,443,447,473,493,527,532,540,546,551,584,632,637,645,651,666,677,699],{"__ignoreMap":5},[272,411,412,414,417,420,423,425,428],{"class":274,"line":275},[272,413,279],{"class":278},[272,415,416],{"class":282}," { defineHandler, ",[272,418,419],{"class":278},"type",[272,421,422],{"class":282}," H3Event } ",[272,424,286],{"class":278},[272,426,427],{"class":289}," \"nitro/h3\"",[272,429,293],{"class":282},[272,431,432,434,437,439,441],{"class":274,"line":296},[272,433,279],{"class":278},[272,435,436],{"class":282}," { defineHandler, defineCachedFunction } ",[272,438,286],{"class":278},[272,440,290],{"class":289},[272,442,293],{"class":282},[272,444,445],{"class":274,"line":303},[272,446,300],{"emptyLinePlaceholder":299},[272,448,449,451,453,456,459,462,465,467,469,471],{"class":274,"line":332},[272,450,306],{"class":278},[272,452,309],{"class":278},[272,454,455],{"class":312}," defineHandler",[272,457,458],{"class":282},"(",[272,460,461],{"class":278},"async",[272,463,464],{"class":282}," (",[272,466,320],{"class":319},[272,468,323],{"class":282},[272,470,326],{"class":278},[272,472,329],{"class":282},[272,474,475,478,481,484,487,490],{"class":274,"line":343},[272,476,477],{"class":278},"  const",[272,479,480],{"class":282}," { ",[272,482,483],{"class":349},"repo",[272,485,486],{"class":282}," } ",[272,488,489],{"class":278},"=",[272,491,492],{"class":282}," event.context.params;\n",[272,494,496,498,501,504,507,510,513,516,519,521,524],{"class":274,"line":495},6,[272,497,477],{"class":278},[272,499,500],{"class":349}," stars",[272,502,503],{"class":278}," =",[272,505,506],{"class":278}," await",[272,508,509],{"class":312}," cachedGHStars",[272,511,512],{"class":282},"(repo).",[272,514,515],{"class":312},"catch",[272,517,518],{"class":282},"(() ",[272,520,326],{"class":278},[272,522,523],{"class":349}," 0",[272,525,526],{"class":282},")\n",[272,528,530],{"class":274,"line":529},7,[272,531,300],{"emptyLinePlaceholder":299},[272,533,535,537],{"class":274,"line":534},8,[272,536,335],{"class":278},[272,538,539],{"class":282}," { repo, stars }\n",[272,541,543],{"class":274,"line":542},9,[272,544,545],{"class":282},"});\n",[272,547,549],{"class":274,"line":548},10,[272,550,300],{"emptyLinePlaceholder":299},[272,552,554,557,559,561,564,566,568,570,572,575,578,580,582],{"class":274,"line":553},11,[272,555,556],{"class":278},"const",[272,558,509],{"class":349},[272,560,503],{"class":278},[272,562,563],{"class":312}," defineCachedFunction",[272,565,458],{"class":282},[272,567,461],{"class":278},[272,569,464],{"class":282},[272,571,483],{"class":319},[272,573,574],{"class":278},":",[272,576,577],{"class":349}," string",[272,579,323],{"class":282},[272,581,326],{"class":278},[272,583,329],{"class":282},[272,585,587,589,592,594,596,599,601,604,606,609,612,615,617,620,623,626,629],{"class":274,"line":586},12,[272,588,477],{"class":278},[272,590,591],{"class":349}," data",[272,593,503],{"class":278},[272,595,506],{"class":278},[272,597,598],{"class":312}," fetch",[272,600,458],{"class":282},[272,602,603],{"class":289},"`https://api.github.com/repos/${",[272,605,483],{"class":282},[272,607,608],{"class":289},"}`",[272,610,611],{"class":282},").",[272,613,614],{"class":312},"then",[272,616,458],{"class":282},[272,618,619],{"class":319},"res",[272,621,622],{"class":278}," =>",[272,624,625],{"class":282}," res.",[272,627,628],{"class":312},"json",[272,630,631],{"class":282},"());\n",[272,633,635],{"class":274,"line":634},13,[272,636,300],{"emptyLinePlaceholder":299},[272,638,640,642],{"class":274,"line":639},14,[272,641,335],{"class":278},[272,643,644],{"class":282}," data.stargazers_count;\n",[272,646,648],{"class":274,"line":647},15,[272,649,650],{"class":282},"}, {\n",[272,652,654,657,659,661,663],{"class":274,"line":653},16,[272,655,656],{"class":282},"  maxAge: ",[272,658,350],{"class":349},[272,660,353],{"class":278},[272,662,356],{"class":349},[272,664,665],{"class":282},",\n",[272,667,669,672,675],{"class":274,"line":668},17,[272,670,671],{"class":282},"  name: ",[272,673,674],{"class":289},"\"ghStars\"",[272,676,665],{"class":282},[272,678,680,683,686,688,690,692,694,696],{"class":274,"line":679},18,[272,681,682],{"class":312},"  getKey",[272,684,685],{"class":282},": (",[272,687,483],{"class":319},[272,689,574],{"class":278},[272,691,577],{"class":349},[272,693,323],{"class":282},[272,695,326],{"class":278},[272,697,698],{"class":282}," repo\n",[272,700,702],{"class":274,"line":701},19,[272,703,545],{"class":282},[233,705,706,707,710,711,714],{},"The stars will be cached in development inside ",[245,708,709],{},".nitro/cache/functions/ghStars/\u003Cowner>/\u003Crepo>.json"," with ",[245,712,713],{},"value"," being the number of stars.",[263,716,719],{"className":717,"code":718,"language":628,"meta":5,"style":5},"language-json shiki shiki-themes github-light github-dark github-dark","{\"expires\":1677851092249,\"value\":43991,\"mtime\":1677847492540,\"integrity\":\"ZUHcsxCWEH\"}\n",[245,720,721],{"__ignoreMap":5},[272,722,723,726,729,731,734,737,740,742,745,747,750,752,755,757,760,762,765],{"class":274,"line":275},[272,724,725],{"class":282},"{",[272,727,728],{"class":349},"\"expires\"",[272,730,574],{"class":282},[272,732,733],{"class":349},"1677851092249",[272,735,736],{"class":282},",",[272,738,739],{"class":349},"\"value\"",[272,741,574],{"class":282},[272,743,744],{"class":349},"43991",[272,746,736],{"class":282},[272,748,749],{"class":349},"\"mtime\"",[272,751,574],{"class":282},[272,753,754],{"class":349},"1677847492540",[272,756,736],{"class":282},[272,758,759],{"class":349},"\"integrity\"",[272,761,574],{"class":282},[272,763,764],{"class":289},"\"ZUHcsxCWEH\"",[272,766,767],{"class":282},"}\n",[374,769,770],{},[233,771,772],{},"Because the cached data is serialized to JSON, it is important that the cached function does not return anything that cannot be serialized, such as Symbols, Maps, Sets…",[774,775,776,779],"callout",{},[233,777,778],{},"If you are using edge workers to host your application, you should follow the instructions below.",[780,781,783,790,801,1049],"collapsible",{"name":782},"Edge workers instructions",[233,784,785,786,789],{},"In edge workers, the instance is destroyed after each request. Nitro automatically uses ",[245,787,788],{},"event.waitUntil"," to keep the instance alive while the cache is being updated while the response is sent to the client.",[233,791,792,793],{},"To ensure that your cached functions work as expected in edge workers, ",[379,794,795,796,798,799,261],{},"you should always pass the ",[245,797,320],{}," as the first argument to the function using ",[245,800,399],{},[263,802,805],{"className":265,"code":803,"filename":407,"highlights":804,"language":268,"meta":5,"style":5},"import { defineCachedFunction } from \"nitro/cache\";\n\n\nexport default defineHandler(async (event) => {\n  const { repo } = event.context.params;\n  const stars = await cachedGHStars(event, repo).catch(() => 0)\n\n  return { repo, stars }\n});\n\nconst cachedGHStars = defineCachedFunction(async (event: H3Event, repo: string) => {\n  const data = await fetch(`https://api.github.com/repos/${repo}`).then(res => res.json());\n\n  return data.stargazers_count;\n}, {\n  maxAge: 60 * 60,\n  name: \"ghStars\",\n  getKey: (event: H3Event, repo: string) => repo\n});\n",[343,548,668],[245,806,807,820,824,828,850,866,891,895,901,905,910,948,984,988,994,998,1010,1019,1045],{"__ignoreMap":5},[272,808,809,811,814,816,818],{"class":274,"line":275},[272,810,279],{"class":278},[272,812,813],{"class":282}," { defineCachedFunction } ",[272,815,286],{"class":278},[272,817,290],{"class":289},[272,819,293],{"class":282},[272,821,822],{"class":274,"line":296},[272,823,300],{"emptyLinePlaceholder":299},[272,825,826],{"class":274,"line":303},[272,827,300],{"emptyLinePlaceholder":299},[272,829,830,832,834,836,838,840,842,844,846,848],{"class":274,"line":332},[272,831,306],{"class":278},[272,833,309],{"class":278},[272,835,455],{"class":312},[272,837,458],{"class":282},[272,839,461],{"class":278},[272,841,464],{"class":282},[272,843,320],{"class":319},[272,845,323],{"class":282},[272,847,326],{"class":278},[272,849,329],{"class":282},[272,851,854,856,858,860,862,864],{"class":852,"line":343},[274,853],"highlight",[272,855,477],{"class":278},[272,857,480],{"class":282},[272,859,483],{"class":349},[272,861,486],{"class":282},[272,863,489],{"class":278},[272,865,492],{"class":282},[272,867,868,870,872,874,876,878,881,883,885,887,889],{"class":274,"line":495},[272,869,477],{"class":278},[272,871,500],{"class":349},[272,873,503],{"class":278},[272,875,506],{"class":278},[272,877,509],{"class":312},[272,879,880],{"class":282},"(event, repo).",[272,882,515],{"class":312},[272,884,518],{"class":282},[272,886,326],{"class":278},[272,888,523],{"class":349},[272,890,526],{"class":282},[272,892,893],{"class":274,"line":529},[272,894,300],{"emptyLinePlaceholder":299},[272,896,897,899],{"class":274,"line":534},[272,898,335],{"class":278},[272,900,539],{"class":282},[272,902,903],{"class":274,"line":542},[272,904,545],{"class":282},[272,906,908],{"class":907,"line":548},[274,853],[272,909,300],{"emptyLinePlaceholder":299},[272,911,912,914,916,918,920,922,924,926,928,930,933,936,938,940,942,944,946],{"class":274,"line":553},[272,913,556],{"class":278},[272,915,509],{"class":349},[272,917,503],{"class":278},[272,919,563],{"class":312},[272,921,458],{"class":282},[272,923,461],{"class":278},[272,925,464],{"class":282},[272,927,320],{"class":319},[272,929,574],{"class":278},[272,931,932],{"class":312}," H3Event",[272,934,935],{"class":282},", ",[272,937,483],{"class":319},[272,939,574],{"class":278},[272,941,577],{"class":349},[272,943,323],{"class":282},[272,945,326],{"class":278},[272,947,329],{"class":282},[272,949,950,952,954,956,958,960,962,964,966,968,970,972,974,976,978,980,982],{"class":274,"line":586},[272,951,477],{"class":278},[272,953,591],{"class":349},[272,955,503],{"class":278},[272,957,506],{"class":278},[272,959,598],{"class":312},[272,961,458],{"class":282},[272,963,603],{"class":289},[272,965,483],{"class":282},[272,967,608],{"class":289},[272,969,611],{"class":282},[272,971,614],{"class":312},[272,973,458],{"class":282},[272,975,619],{"class":319},[272,977,622],{"class":278},[272,979,625],{"class":282},[272,981,628],{"class":312},[272,983,631],{"class":282},[272,985,986],{"class":274,"line":634},[272,987,300],{"emptyLinePlaceholder":299},[272,989,990,992],{"class":274,"line":639},[272,991,335],{"class":278},[272,993,644],{"class":282},[272,995,996],{"class":274,"line":647},[272,997,650],{"class":282},[272,999,1000,1002,1004,1006,1008],{"class":274,"line":653},[272,1001,656],{"class":282},[272,1003,350],{"class":349},[272,1005,353],{"class":278},[272,1007,356],{"class":349},[272,1009,665],{"class":282},[272,1011,1013,1015,1017],{"class":1012,"line":668},[274,853],[272,1014,671],{"class":282},[272,1016,674],{"class":289},[272,1018,665],{"class":282},[272,1020,1021,1023,1025,1027,1029,1031,1033,1035,1037,1039,1041,1043],{"class":274,"line":679},[272,1022,682],{"class":312},[272,1024,685],{"class":282},[272,1026,320],{"class":319},[272,1028,574],{"class":278},[272,1030,932],{"class":312},[272,1032,935],{"class":282},[272,1034,483],{"class":319},[272,1036,574],{"class":278},[272,1038,577],{"class":349},[272,1040,323],{"class":282},[272,1042,326],{"class":278},[272,1044,698],{"class":282},[272,1046,1047],{"class":274,"line":701},[272,1048,545],{"class":282},[233,1050,1051],{},"This way, the function will be able to keep the instance alive while the cache is being updated without slowing down the response to the client.",[237,1053,1055],{"id":1054},"using-route-rules","Using route rules",[233,1057,1058],{},"This feature enables you to add caching routes based on a glob pattern directly in the main configuration file. This is especially useful to have a global cache strategy for a part of your application.",[233,1060,1061,1062,1065],{},"Cache all the blog routes for 1 hour with ",[245,1063,1064],{},"stale-while-revalidate"," behavior:",[263,1067,1070],{"className":265,"code":1068,"filename":1069,"language":268,"meta":5,"style":5},"import { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  routeRules: {\n    \"/blog/**\": { cache: { maxAge: 60 * 60 } },\n  },\n});\n","nitro.config.ts",[245,1071,1072,1086,1090,1102,1107,1124,1129],{"__ignoreMap":5},[272,1073,1074,1076,1079,1081,1084],{"class":274,"line":275},[272,1075,279],{"class":278},[272,1077,1078],{"class":282}," { defineNitroConfig } ",[272,1080,286],{"class":278},[272,1082,1083],{"class":289}," \"nitro/config\"",[272,1085,293],{"class":282},[272,1087,1088],{"class":274,"line":296},[272,1089,300],{"emptyLinePlaceholder":299},[272,1091,1092,1094,1096,1099],{"class":274,"line":303},[272,1093,306],{"class":278},[272,1095,309],{"class":278},[272,1097,1098],{"class":312}," defineNitroConfig",[272,1100,1101],{"class":282},"({\n",[272,1103,1104],{"class":274,"line":332},[272,1105,1106],{"class":282},"  routeRules: {\n",[272,1108,1109,1112,1115,1117,1119,1121],{"class":274,"line":343},[272,1110,1111],{"class":289},"    \"/blog/**\"",[272,1113,1114],{"class":282},": { cache: { maxAge: ",[272,1116,350],{"class":349},[272,1118,353],{"class":278},[272,1120,356],{"class":349},[272,1122,1123],{"class":282}," } },\n",[272,1125,1126],{"class":274,"line":495},[272,1127,1128],{"class":282},"  },\n",[272,1130,1131],{"class":274,"line":529},[272,1132,545],{"class":282},[233,1134,1135,1136,1140,1141,1144],{},"If we want to use a ",[257,1137,1139],{"href":1138},"#cache-storage","custom cache storage"," mount point, we can use the ",[245,1142,1143],{},"base"," option.",[263,1146,1148],{"className":265,"code":1147,"filename":1069,"language":268,"meta":5,"style":5},"import { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  storage: {\n    redis: {\n      driver: \"redis\",\n      url: \"redis://localhost:6379\",\n    },\n  },\n  routeRules: {\n    \"/blog/**\": { cache: { maxAge: 60 * 60, base: \"redis\" } },\n  },\n});\n",[245,1149,1150,1162,1166,1176,1181,1186,1196,1206,1211,1215,1219,1238,1242],{"__ignoreMap":5},[272,1151,1152,1154,1156,1158,1160],{"class":274,"line":275},[272,1153,279],{"class":278},[272,1155,1078],{"class":282},[272,1157,286],{"class":278},[272,1159,1083],{"class":289},[272,1161,293],{"class":282},[272,1163,1164],{"class":274,"line":296},[272,1165,300],{"emptyLinePlaceholder":299},[272,1167,1168,1170,1172,1174],{"class":274,"line":303},[272,1169,306],{"class":278},[272,1171,309],{"class":278},[272,1173,1098],{"class":312},[272,1175,1101],{"class":282},[272,1177,1178],{"class":274,"line":332},[272,1179,1180],{"class":282},"  storage: {\n",[272,1182,1183],{"class":274,"line":343},[272,1184,1185],{"class":282},"    redis: {\n",[272,1187,1188,1191,1194],{"class":274,"line":495},[272,1189,1190],{"class":282},"      driver: ",[272,1192,1193],{"class":289},"\"redis\"",[272,1195,665],{"class":282},[272,1197,1198,1201,1204],{"class":274,"line":529},[272,1199,1200],{"class":282},"      url: ",[272,1202,1203],{"class":289},"\"redis://localhost:6379\"",[272,1205,665],{"class":282},[272,1207,1208],{"class":274,"line":534},[272,1209,1210],{"class":282},"    },\n",[272,1212,1213],{"class":274,"line":542},[272,1214,1128],{"class":282},[272,1216,1217],{"class":274,"line":548},[272,1218,1106],{"class":282},[272,1220,1221,1223,1225,1227,1229,1231,1234,1236],{"class":274,"line":553},[272,1222,1111],{"class":289},[272,1224,1114],{"class":282},[272,1226,350],{"class":349},[272,1228,353],{"class":278},[272,1230,356],{"class":349},[272,1232,1233],{"class":282},", base: ",[272,1235,1193],{"class":289},[272,1237,1123],{"class":282},[272,1239,1240],{"class":274,"line":586},[272,1241,1128],{"class":282},[272,1243,1244],{"class":274,"line":634},[272,1245,545],{"class":282},[237,1247,1249],{"id":1248},"cache-storage","Cache storage",[233,1251,1252,1253,1256],{},"Nitro stores the data in the ",[245,1254,1255],{},"cache"," storage mount point.",[1258,1259,1260,1271],"ul",{},[1261,1262,1263,1264,1270],"li",{},"In production, it will use the ",[257,1265,1269],{"href":1266,"rel":1267},"https://unstorage.unjs.io/drivers/memory",[1268],"nofollow","memory driver"," by default.",[1261,1272,1273,1274,1279,1280,611],{},"In development, it will use the ",[257,1275,1278],{"href":1276,"rel":1277},"https://unstorage.unjs.io/drivers/fs",[1268],"filesystem driver",", writing to a temporary dir (",[245,1281,1282],{},".nitro/cache",[233,1284,1285,1286,1288,1289,1292],{},"To overwrite the production storage, set the ",[245,1287,1255],{}," mount point using the ",[245,1290,1291],{},"storage"," option:",[263,1294,1296],{"className":265,"code":1295,"filename":1069,"language":268,"meta":5,"style":5},"import { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  storage: {\n    cache: {\n      driver: 'redis',\n      /* redis connector options */\n    }\n  }\n})\n",[245,1297,1298,1310,1314,1324,1328,1333,1342,1348,1353,1358],{"__ignoreMap":5},[272,1299,1300,1302,1304,1306,1308],{"class":274,"line":275},[272,1301,279],{"class":278},[272,1303,1078],{"class":282},[272,1305,286],{"class":278},[272,1307,1083],{"class":289},[272,1309,293],{"class":282},[272,1311,1312],{"class":274,"line":296},[272,1313,300],{"emptyLinePlaceholder":299},[272,1315,1316,1318,1320,1322],{"class":274,"line":303},[272,1317,306],{"class":278},[272,1319,309],{"class":278},[272,1321,1098],{"class":312},[272,1323,1101],{"class":282},[272,1325,1326],{"class":274,"line":332},[272,1327,1180],{"class":282},[272,1329,1330],{"class":274,"line":343},[272,1331,1332],{"class":282},"    cache: {\n",[272,1334,1335,1337,1340],{"class":274,"line":495},[272,1336,1190],{"class":282},[272,1338,1339],{"class":289},"'redis'",[272,1341,665],{"class":282},[272,1343,1344],{"class":274,"line":529},[272,1345,1347],{"class":1346},"sCsY4","      /* redis connector options */\n",[272,1349,1350],{"class":274,"line":534},[272,1351,1352],{"class":282},"    }\n",[272,1354,1355],{"class":274,"line":542},[272,1356,1357],{"class":282},"  }\n",[272,1359,1360],{"class":274,"line":548},[272,1361,1362],{"class":282},"})\n",[233,1364,1365,1366,1292],{},"In development, you can also overwrite the cache mount point using the ",[245,1367,1368],{},"devStorage",[263,1370,1372],{"className":265,"code":1371,"filename":1069,"language":268,"meta":5,"style":5},"import { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  storage: {\n    cache: {\n      // production cache storage\n    },\n  },\n  devStorage: {\n    cache: {\n      // development cache storage\n    }\n  }\n})\n",[245,1373,1374,1386,1390,1400,1404,1408,1413,1417,1421,1426,1430,1435,1439,1443],{"__ignoreMap":5},[272,1375,1376,1378,1380,1382,1384],{"class":274,"line":275},[272,1377,279],{"class":278},[272,1379,1078],{"class":282},[272,1381,286],{"class":278},[272,1383,1083],{"class":289},[272,1385,293],{"class":282},[272,1387,1388],{"class":274,"line":296},[272,1389,300],{"emptyLinePlaceholder":299},[272,1391,1392,1394,1396,1398],{"class":274,"line":303},[272,1393,306],{"class":278},[272,1395,309],{"class":278},[272,1397,1098],{"class":312},[272,1399,1101],{"class":282},[272,1401,1402],{"class":274,"line":332},[272,1403,1180],{"class":282},[272,1405,1406],{"class":274,"line":343},[272,1407,1332],{"class":282},[272,1409,1410],{"class":274,"line":495},[272,1411,1412],{"class":1346},"      // production cache storage\n",[272,1414,1415],{"class":274,"line":529},[272,1416,1210],{"class":282},[272,1418,1419],{"class":274,"line":534},[272,1420,1128],{"class":282},[272,1422,1423],{"class":274,"line":542},[272,1424,1425],{"class":282},"  devStorage: {\n",[272,1427,1428],{"class":274,"line":548},[272,1429,1332],{"class":282},[272,1431,1432],{"class":274,"line":553},[272,1433,1434],{"class":1346},"      // development cache storage\n",[272,1436,1437],{"class":274,"line":586},[272,1438,1352],{"class":282},[272,1440,1441],{"class":274,"line":634},[272,1442,1357],{"class":282},[272,1444,1445],{"class":274,"line":639},[272,1446,1362],{"class":282},[237,1448,1449],{"id":371},"Options",[233,1451,1452,1453,1455,1456,1458],{},"The ",[245,1454,247],{}," and ",[245,1457,399],{}," functions accept the following options:",[1460,1461,1462,1475,1485,1499,1513,1526,1539,1556,1571,1581,1589],"field-group",{},[1463,1464,1466],"field",{"name":1143,"type":1465},"string",[233,1467,1468,1469,1472,1473,261],{},"Name of the storage mountpoint to use for caching. ",[1470,1471],"br",{},"\nDefault to ",[245,1474,1255],{},[1463,1476,1478],{"name":1477,"type":1465},"name",[233,1479,1480,1481,1484],{},"Guessed from function name if not provided, and falls back to ",[245,1482,1483],{},"'_'"," otherwise.",[1463,1486,1488],{"name":1487,"type":1465},"group",[233,1489,1490,1491,1494,1495,1498],{},"Defaults to ",[245,1492,1493],{},"'nitro/handlers'"," for handlers and ",[245,1496,1497],{},"'nitro/functions'"," for functions.",[1463,1500,1503],{"name":1501,"type":1502},"getKey()","(...args) => string",[233,1504,1505,1506,1509,1510,1512],{},"A function that accepts the same arguments as the original function and returns a cache key (",[245,1507,1508],{},"String","). ",[1470,1511],{},"\nIf not provided, a built-in hash function will be used to generate a key based on the function arguments.",[1463,1514,1516],{"name":1515,"type":1465},"integrity",[233,1517,1518,1519,1521,1522,1525],{},"A value that invalidates the cache when changed. ",[1470,1520],{},"\nBy default, it is computed from ",[379,1523,1524],{},"function code",", used in development to invalidate the cache when the function code changes.",[1463,1527,1530],{"name":1528,"type":1529},"maxAge","number",[233,1531,1532,1533,1472,1535,1538],{},"Maximum age that cache is valid, in seconds. ",[1470,1534],{},[245,1536,1537],{},"1"," (second).",[1463,1540,1542],{"name":1541,"type":1529},"staleMaxAge",[233,1543,1544,1545,1548,1549,1551,1552,1555],{},"Maximum age that a stale cache is valid, in seconds. If set to ",[245,1546,1547],{},"-1"," a stale value will still be sent to the client while the cache updates in the background. ",[1470,1550],{},"\nDefaults to ",[245,1553,1554],{},"0"," (disabled).",[1463,1557,1560],{"name":1558,"type":1559},"swr","boolean",[233,1561,1562,1563,1565,1566,1551,1568,261],{},"Enable ",[245,1564,1064],{}," behavior to serve a stale cached response while asynchronously revalidating it. ",[1470,1567],{},[245,1569,1570],{},"true",[1463,1572,1575],{"name":1573,"type":1574},"shouldInvalidateCache()","(..args) => boolean",[233,1576,1577,1578,1580],{},"A function that returns a ",[245,1579,1559],{}," to invalidate the current cache and create a new one.",[1463,1582,1584],{"name":1583,"type":1574},"shouldBypassCache()",[233,1585,1577,1586,1588],{},[245,1587,1559],{}," to bypass the current cache without invalidating the existing entry.",[1463,1590,1592],{"name":387,"type":1591},"string[]",[233,1593,1594,1595,1600,1601,1604],{},"An array of request headers to be considered for the cache, ",[257,1596,1599],{"href":1597,"rel":1598},"https://github.com/nitrojs/nitro/issues/1031",[1268],"learn more",". If utilizing in a multi-tenant environment, you may want to pass ",[245,1602,1603],{},"['host', 'x-forwarded-host']"," to ensure these headers are not discarded and that the cache is unique per tenant.",[237,1606,1608],{"id":1607},"cache-keys-and-invalidation","Cache keys and invalidation",[233,1610,1611,1612,1614,1615,1617],{},"When using the ",[245,1613,399],{}," or ",[245,1616,247],{}," functions, the cache key is generated using the following pattern:",[263,1619,1621],{"className":265,"code":1620,"language":268,"meta":5,"style":5},"`${options.group}:${options.name}:${options.getKey(...args)}.json`\n",[245,1622,1623],{"__ignoreMap":5},[272,1624,1625,1628,1630,1632,1634,1637,1639,1641,1643,1645,1647,1649,1652,1654,1657,1660,1663],{"class":274,"line":275},[272,1626,1627],{"class":289},"`${",[272,1629,371],{"class":282},[272,1631,261],{"class":289},[272,1633,1487],{"class":282},[272,1635,1636],{"class":289},"}:${",[272,1638,371],{"class":282},[272,1640,261],{"class":289},[272,1642,1477],{"class":282},[272,1644,1636],{"class":289},[272,1646,371],{"class":282},[272,1648,261],{"class":289},[272,1650,1651],{"class":312},"getKey",[272,1653,458],{"class":289},[272,1655,1656],{"class":278},"...",[272,1658,1659],{"class":282},"args",[272,1661,1662],{"class":289},")",[272,1664,1665],{"class":289},"}.json`\n",[233,1667,1668],{},"For example, the following function:",[263,1670,1672],{"className":265,"code":1671,"language":268,"meta":5,"style":5},"import { defineCachedFunction } from \"nitro/cache\";\n\nconst getAccessToken = defineCachedFunction(() => {\n  return String(Date.now())\n}, {\n  maxAge: 10,\n  name: \"getAccessToken\",\n  getKey: () => \"default\"\n});\n",[245,1673,1674,1686,1690,1707,1723,1727,1736,1745,1757],{"__ignoreMap":5},[272,1675,1676,1678,1680,1682,1684],{"class":274,"line":275},[272,1677,279],{"class":278},[272,1679,813],{"class":282},[272,1681,286],{"class":278},[272,1683,290],{"class":289},[272,1685,293],{"class":282},[272,1687,1688],{"class":274,"line":296},[272,1689,300],{"emptyLinePlaceholder":299},[272,1691,1692,1694,1697,1699,1701,1703,1705],{"class":274,"line":303},[272,1693,556],{"class":278},[272,1695,1696],{"class":349}," getAccessToken",[272,1698,503],{"class":278},[272,1700,563],{"class":312},[272,1702,518],{"class":282},[272,1704,326],{"class":278},[272,1706,329],{"class":282},[272,1708,1709,1711,1714,1717,1720],{"class":274,"line":332},[272,1710,335],{"class":278},[272,1712,1713],{"class":312}," String",[272,1715,1716],{"class":282},"(Date.",[272,1718,1719],{"class":312},"now",[272,1721,1722],{"class":282},"())\n",[272,1724,1725],{"class":274,"line":343},[272,1726,650],{"class":282},[272,1728,1729,1731,1734],{"class":274,"line":495},[272,1730,656],{"class":282},[272,1732,1733],{"class":349},"10",[272,1735,665],{"class":282},[272,1737,1738,1740,1743],{"class":274,"line":529},[272,1739,671],{"class":282},[272,1741,1742],{"class":289},"\"getAccessToken\"",[272,1744,665],{"class":282},[272,1746,1747,1749,1752,1754],{"class":274,"line":534},[272,1748,682],{"class":312},[272,1750,1751],{"class":282},": () ",[272,1753,326],{"class":278},[272,1755,1756],{"class":289}," \"default\"\n",[272,1758,1759],{"class":274,"line":542},[272,1760,545],{"class":282},[233,1762,1763],{},"Will generate the following cache key:",[263,1765,1767],{"className":265,"code":1766,"language":268,"meta":5,"style":5},"nitro:functions:getAccessToken:default.json\n",[245,1768,1769],{"__ignoreMap":5},[272,1770,1771,1774,1776,1779,1781,1784],{"class":274,"line":275},[272,1772,1773],{"class":312},"nitro",[272,1775,574],{"class":282},[272,1777,1778],{"class":312},"functions",[272,1780,574],{"class":282},[272,1782,1783],{"class":312},"getAccessToken",[272,1785,1786],{"class":282},":default.json\n",[233,1788,1789],{},"You can invalidate the cached function entry with:",[263,1791,1793],{"className":265,"code":1792,"language":268,"meta":5,"style":5},"import { useStorage } from \"nitro/storage\";\n\nawait useStorage('cache').removeItem('nitro:functions:getAccessToken:default.json')\n",[245,1794,1795,1809,1813],{"__ignoreMap":5},[272,1796,1797,1799,1802,1804,1807],{"class":274,"line":275},[272,1798,279],{"class":278},[272,1800,1801],{"class":282}," { useStorage } ",[272,1803,286],{"class":278},[272,1805,1806],{"class":289}," \"nitro/storage\"",[272,1808,293],{"class":282},[272,1810,1811],{"class":274,"line":296},[272,1812,300],{"emptyLinePlaceholder":299},[272,1814,1815,1818,1821,1823,1826,1828,1831,1833,1836],{"class":274,"line":303},[272,1816,1817],{"class":278},"await",[272,1819,1820],{"class":312}," useStorage",[272,1822,458],{"class":282},[272,1824,1825],{"class":289},"'cache'",[272,1827,611],{"class":282},[272,1829,1830],{"class":312},"removeItem",[272,1832,458],{"class":282},[272,1834,1835],{"class":289},"'nitro:functions:getAccessToken:default.json'",[272,1837,526],{"class":282},[1839,1840,1841],"read-more",{"to":69},[233,1842,1843],{},"Read more about the Nitro storage.",[1845,1846,1847],"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 .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 .suiK_, html code.shiki .suiK_{--shiki-light:#005CC5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}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);}html pre.shiki code .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":5,"searchDepth":296,"depth":296,"links":1849},[1850,1851,1852,1853,1854,1855],{"id":239,"depth":296,"text":240},{"id":392,"depth":296,"text":393},{"id":1054,"depth":296,"text":1055},{"id":1248,"depth":296,"text":1249},{"id":371,"depth":296,"text":1449},{"id":1607,"depth":296,"text":1608},"Nitro provides a caching system built on top of the storage layer.","md",{"icon":66},{"icon":66},{"title":63,"description":1856},"WLcTEjeK9EmgUIVHJXv6mLRQa7sf0Il-c5O6dZPHusE",[1863,1865],{"title":58,"path":59,"stem":60,"description":1864,"icon":61,"children":-1},"Use a server entry to create a global middleware that runs for all routes before they are matched.",{"title":68,"path":69,"stem":70,"description":1866,"icon":71,"children":-1},"Nitro provides a built-in storage layer that can abstract filesystem or database or any other data source.",1773050250745]