[{"data":1,"prerenderedAt":853},["ShallowReactive",2],{"post-caching-nitro-endpoints-in-nuxt":3,"content-query-H6R8T2o5WH":487},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"posted_at":10,"slug":11,"intro":12,"readingTime":13,"body":18,"_type":481,"_id":482,"_source":483,"_file":484,"_stem":485,"_extension":486},"/posts/caching-nitro-endpoints-in-nuxt","posts",false,"","Caching Nitro endpoints in Nuxt","There is a caching mechanism built into Nitro, the server engine of Nuxt, that might be a little less known because it's documentation is not currently in the Nuxt docs, it's only in the Nitro docs. Caching Nuxt/Nitro event handlers is a great way to improve performance and speed on endpoints by storing the response of incoming requests in JSON files so that the same requests can be served a lot faster. This might typically be used on endpoints where the data doesn't change much or where an endpoint is slow due to a lot of computing so caching will speed it up if available.","2025-01-27T23:00:00.000Z","caching-nitro-endpoints-in-nuxt","There is a caching mechanism built into Nitro, the server engine of Nuxt, that might be a little less known because it's documentation is not currently in the Nuxt docs, they are only in the Nitro docs.",{"text":14,"minutes":15,"time":16,"words":17},"2 min read",1.94,116400,388,{"type":19,"children":20,"toc":479},"root",[21,28,66,395,400,429,449,455,473],{"type":22,"tag":23,"props":24,"children":25},"element","p",{},[26],{"type":27,"value":9},"text",{"type":22,"tag":23,"props":29,"children":30},{},[31,33,40,42,48,50,56,58,64],{"type":27,"value":32},"It's super easy to do as well by replacing ",{"type":22,"tag":34,"props":35,"children":37},"code",{"className":36},[],[38],{"type":27,"value":39},"defineEventHandler",{"type":27,"value":41}," on an endpoint with ",{"type":22,"tag":34,"props":43,"children":45},{"className":44},[],[46],{"type":27,"value":47},"defineCachedEventHandler",{"type":27,"value":49},". It takes an additional parameter which defines the options for the handler. It has many options, but the main one that you need is ",{"type":22,"tag":34,"props":51,"children":53},{"className":52},[],[54],{"type":27,"value":55},"maxAge",{"type":27,"value":57}," which sets the maximum time that cache is valid, in seconds. If you have disabled auto-imports like me, you can import it from ",{"type":22,"tag":34,"props":59,"children":61},{"className":60},[],[62],{"type":27,"value":63},"nitropack/runtime",{"type":27,"value":65},".",{"type":22,"tag":67,"props":68,"children":73},"pre",{"className":69,"code":70,"filename":71,"language":72,"meta":7,"style":7},"language-ts shiki shiki-themes dracula-soft","import { defineCachedEventHandler } from 'nitropack/runtime'\n\nexport default defineCachedEventHandler(async () => {\n  // Some asynchronous logic\n  await new Promise(resolve => setTimeout(resolve, 500))\n\n  return {\n    posted_at: '2025-01-27T23:00:00.000Z',\n    title: 'Caching Nitro endpoints in Nuxt',\n    slug: 'caching-nitro-endpoints-in-nuxt',\n  }\n}, { maxAge: 60 * 60 }) // 1 hour\n","server/api/index.ts","ts",[74],{"type":22,"tag":34,"props":75,"children":76},{"__ignoreMap":7},[77,116,126,171,181,238,246,259,291,320,349,358],{"type":22,"tag":78,"props":79,"children":82},"span",{"class":80,"line":81},"line",1,[83,89,95,100,106,111],{"type":22,"tag":78,"props":84,"children":86},{"style":85},"--shiki-default:#F286C4",[87],{"type":27,"value":88},"import",{"type":22,"tag":78,"props":90,"children":92},{"style":91},"--shiki-default:#F6F6F4",[93],{"type":27,"value":94}," { defineCachedEventHandler } ",{"type":22,"tag":78,"props":96,"children":97},{"style":85},[98],{"type":27,"value":99},"from",{"type":22,"tag":78,"props":101,"children":103},{"style":102},"--shiki-default:#DEE492",[104],{"type":27,"value":105}," '",{"type":22,"tag":78,"props":107,"children":109},{"style":108},"--shiki-default:#E7EE98",[110],{"type":27,"value":63},{"type":22,"tag":78,"props":112,"children":113},{"style":102},[114],{"type":27,"value":115},"'\n",{"type":22,"tag":78,"props":117,"children":119},{"class":80,"line":118},2,[120],{"type":22,"tag":78,"props":121,"children":123},{"emptyLinePlaceholder":122},true,[124],{"type":27,"value":125},"\n",{"type":22,"tag":78,"props":127,"children":129},{"class":80,"line":128},3,[130,135,140,146,151,156,161,166],{"type":22,"tag":78,"props":131,"children":132},{"style":85},[133],{"type":27,"value":134},"export",{"type":22,"tag":78,"props":136,"children":137},{"style":85},[138],{"type":27,"value":139}," default",{"type":22,"tag":78,"props":141,"children":143},{"style":142},"--shiki-default:#62E884",[144],{"type":27,"value":145}," defineCachedEventHandler",{"type":22,"tag":78,"props":147,"children":148},{"style":91},[149],{"type":27,"value":150},"(",{"type":22,"tag":78,"props":152,"children":153},{"style":85},[154],{"type":27,"value":155},"async",{"type":22,"tag":78,"props":157,"children":158},{"style":91},[159],{"type":27,"value":160}," () ",{"type":22,"tag":78,"props":162,"children":163},{"style":85},[164],{"type":27,"value":165},"=>",{"type":22,"tag":78,"props":167,"children":168},{"style":91},[169],{"type":27,"value":170}," {\n",{"type":22,"tag":78,"props":172,"children":174},{"class":80,"line":173},4,[175],{"type":22,"tag":78,"props":176,"children":178},{"style":177},"--shiki-default:#7B7F8B",[179],{"type":27,"value":180},"  // Some asynchronous logic\n",{"type":22,"tag":78,"props":182,"children":184},{"class":80,"line":183},5,[185,190,196,202,206,212,217,222,227,233],{"type":22,"tag":78,"props":186,"children":187},{"style":85},[188],{"type":27,"value":189},"  await",{"type":22,"tag":78,"props":191,"children":193},{"style":192},"--shiki-default:#F286C4;--shiki-default-font-weight:bold",[194],{"type":27,"value":195}," new",{"type":22,"tag":78,"props":197,"children":199},{"style":198},"--shiki-default:#97E1F1;--shiki-default-font-style:italic",[200],{"type":27,"value":201}," Promise",{"type":22,"tag":78,"props":203,"children":204},{"style":91},[205],{"type":27,"value":150},{"type":22,"tag":78,"props":207,"children":209},{"style":208},"--shiki-default:#FFB86C;--shiki-default-font-style:italic",[210],{"type":27,"value":211},"resolve",{"type":22,"tag":78,"props":213,"children":214},{"style":85},[215],{"type":27,"value":216}," =>",{"type":22,"tag":78,"props":218,"children":219},{"style":142},[220],{"type":27,"value":221}," setTimeout",{"type":22,"tag":78,"props":223,"children":224},{"style":91},[225],{"type":27,"value":226},"(resolve, ",{"type":22,"tag":78,"props":228,"children":230},{"style":229},"--shiki-default:#BF9EEE",[231],{"type":27,"value":232},"500",{"type":22,"tag":78,"props":234,"children":235},{"style":91},[236],{"type":27,"value":237},"))\n",{"type":22,"tag":78,"props":239,"children":241},{"class":80,"line":240},6,[242],{"type":22,"tag":78,"props":243,"children":244},{"emptyLinePlaceholder":122},[245],{"type":27,"value":125},{"type":22,"tag":78,"props":247,"children":249},{"class":80,"line":248},7,[250,255],{"type":22,"tag":78,"props":251,"children":252},{"style":85},[253],{"type":27,"value":254},"  return",{"type":22,"tag":78,"props":256,"children":257},{"style":91},[258],{"type":27,"value":170},{"type":22,"tag":78,"props":260,"children":262},{"class":80,"line":261},8,[263,268,273,277,281,286],{"type":22,"tag":78,"props":264,"children":265},{"style":91},[266],{"type":27,"value":267},"    posted_at",{"type":22,"tag":78,"props":269,"children":270},{"style":85},[271],{"type":27,"value":272},":",{"type":22,"tag":78,"props":274,"children":275},{"style":102},[276],{"type":27,"value":105},{"type":22,"tag":78,"props":278,"children":279},{"style":108},[280],{"type":27,"value":10},{"type":22,"tag":78,"props":282,"children":283},{"style":102},[284],{"type":27,"value":285},"'",{"type":22,"tag":78,"props":287,"children":288},{"style":91},[289],{"type":27,"value":290},",\n",{"type":22,"tag":78,"props":292,"children":294},{"class":80,"line":293},9,[295,300,304,308,312,316],{"type":22,"tag":78,"props":296,"children":297},{"style":91},[298],{"type":27,"value":299},"    title",{"type":22,"tag":78,"props":301,"children":302},{"style":85},[303],{"type":27,"value":272},{"type":22,"tag":78,"props":305,"children":306},{"style":102},[307],{"type":27,"value":105},{"type":22,"tag":78,"props":309,"children":310},{"style":108},[311],{"type":27,"value":8},{"type":22,"tag":78,"props":313,"children":314},{"style":102},[315],{"type":27,"value":285},{"type":22,"tag":78,"props":317,"children":318},{"style":91},[319],{"type":27,"value":290},{"type":22,"tag":78,"props":321,"children":323},{"class":80,"line":322},10,[324,329,333,337,341,345],{"type":22,"tag":78,"props":325,"children":326},{"style":91},[327],{"type":27,"value":328},"    slug",{"type":22,"tag":78,"props":330,"children":331},{"style":85},[332],{"type":27,"value":272},{"type":22,"tag":78,"props":334,"children":335},{"style":102},[336],{"type":27,"value":105},{"type":22,"tag":78,"props":338,"children":339},{"style":108},[340],{"type":27,"value":11},{"type":22,"tag":78,"props":342,"children":343},{"style":102},[344],{"type":27,"value":285},{"type":22,"tag":78,"props":346,"children":347},{"style":91},[348],{"type":27,"value":290},{"type":22,"tag":78,"props":350,"children":352},{"class":80,"line":351},11,[353],{"type":22,"tag":78,"props":354,"children":355},{"style":91},[356],{"type":27,"value":357},"  }\n",{"type":22,"tag":78,"props":359,"children":361},{"class":80,"line":360},12,[362,367,371,376,381,385,390],{"type":22,"tag":78,"props":363,"children":364},{"style":91},[365],{"type":27,"value":366},"}, { maxAge",{"type":22,"tag":78,"props":368,"children":369},{"style":85},[370],{"type":27,"value":272},{"type":22,"tag":78,"props":372,"children":373},{"style":229},[374],{"type":27,"value":375}," 60",{"type":22,"tag":78,"props":377,"children":378},{"style":85},[379],{"type":27,"value":380}," *",{"type":22,"tag":78,"props":382,"children":383},{"style":229},[384],{"type":27,"value":375},{"type":22,"tag":78,"props":386,"children":387},{"style":91},[388],{"type":27,"value":389}," }) ",{"type":22,"tag":78,"props":391,"children":392},{"style":177},[393],{"type":27,"value":394},"// 1 hour\n",{"type":22,"tag":23,"props":396,"children":397},{},[398],{"type":27,"value":399},"This will do two important things:",{"type":22,"tag":401,"props":402,"children":403},"ol",{},[404,410],{"type":22,"tag":405,"props":406,"children":407},"li",{},[408],{"type":27,"value":409},"Cache the response of the request in Nitro's cache system",{"type":22,"tag":405,"props":411,"children":412},{},[413,415,421,423],{"type":27,"value":414},"Add the ",{"type":22,"tag":34,"props":416,"children":418},{"className":417},[],[419],{"type":27,"value":420},"cache-control",{"type":27,"value":422}," header with ",{"type":22,"tag":34,"props":424,"children":426},{"className":425},[],[427],{"type":27,"value":428},"max-age=3600",{"type":22,"tag":23,"props":430,"children":431},{},[432,434,440,442,447],{"type":27,"value":433},"You can see the cached response in Nitro when running the dev server by going into ",{"type":22,"tag":34,"props":435,"children":437},{"className":436},[],[438],{"type":27,"value":439},".nuxt/cache/nitro/handlers",{"type":27,"value":441},". If you hit the endpoint, you'll see a JSON file be created which will have the response body as well as some other response metadata. You'll also see the ",{"type":22,"tag":34,"props":443,"children":445},{"className":444},[],[446],{"type":27,"value":420},{"type":27,"value":448}," header. Nuxt/Nitro will now serve this cached JSON as the response until the cache expires in 1 hour.",{"type":22,"tag":450,"props":451,"children":452},"tip",{},[453],{"type":27,"value":454},"\nThe Nuxt Devtools has a great way of testing the API endpoints. Open Nuxt Devtools, press Command + K, then search for \"Server Routes\".\n",{"type":22,"tag":23,"props":456,"children":457},{},[458,460,465,466,471],{"type":27,"value":459},"In the browser devtools, check the response headers of the request and you'll see the ",{"type":22,"tag":34,"props":461,"children":463},{"className":462},[],[464],{"type":27,"value":420},{"type":27,"value":422},{"type":22,"tag":34,"props":467,"children":469},{"className":468},[],[470],{"type":27,"value":428},{"type":27,"value":472},". This will tell the browser that it should cache the response as well and reuse it for subsequent requests until it expires. Try hitting the endpoint again and you'll see the browser doesn't hit the API at all, but instead retrieves it from disk cache. You can prove this on the server side by deleting the cached JSON files and hitting the API again. If the browser retrieves it from disk cache the API does recreate the JSON file again.",{"type":22,"tag":474,"props":475,"children":476},"style",{},[477],{"type":27,"value":478},"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);}",{"title":7,"searchDepth":118,"depth":118,"links":480},[],"markdown","content:posts:caching-nitro-endpoints-in-nuxt.md","content","posts/caching-nitro-endpoints-in-nuxt.md","posts/caching-nitro-endpoints-in-nuxt","md",{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"posted_at":10,"slug":11,"intro":12,"readingTime":488,"body":489,"_type":481,"_id":482,"_source":483,"_file":484,"_stem":485,"_extension":486},{"text":14,"minutes":15,"time":16,"words":17},{"type":19,"children":490,"toc":851},[491,495,523,785,789,811,827,831,847],{"type":22,"tag":23,"props":492,"children":493},{},[494],{"type":27,"value":9},{"type":22,"tag":23,"props":496,"children":497},{},[498,499,504,505,510,511,516,517,522],{"type":27,"value":32},{"type":22,"tag":34,"props":500,"children":502},{"className":501},[],[503],{"type":27,"value":39},{"type":27,"value":41},{"type":22,"tag":34,"props":506,"children":508},{"className":507},[],[509],{"type":27,"value":47},{"type":27,"value":49},{"type":22,"tag":34,"props":512,"children":514},{"className":513},[],[515],{"type":27,"value":55},{"type":27,"value":57},{"type":22,"tag":34,"props":518,"children":520},{"className":519},[],[521],{"type":27,"value":63},{"type":27,"value":65},{"type":22,"tag":67,"props":524,"children":525},{"className":69,"code":70,"filename":71,"language":72,"meta":7,"style":7},[526],{"type":22,"tag":34,"props":527,"children":528},{"__ignoreMap":7},[529,556,563,598,605,648,655,666,693,720,747,754],{"type":22,"tag":78,"props":530,"children":531},{"class":80,"line":81},[532,536,540,544,548,552],{"type":22,"tag":78,"props":533,"children":534},{"style":85},[535],{"type":27,"value":88},{"type":22,"tag":78,"props":537,"children":538},{"style":91},[539],{"type":27,"value":94},{"type":22,"tag":78,"props":541,"children":542},{"style":85},[543],{"type":27,"value":99},{"type":22,"tag":78,"props":545,"children":546},{"style":102},[547],{"type":27,"value":105},{"type":22,"tag":78,"props":549,"children":550},{"style":108},[551],{"type":27,"value":63},{"type":22,"tag":78,"props":553,"children":554},{"style":102},[555],{"type":27,"value":115},{"type":22,"tag":78,"props":557,"children":558},{"class":80,"line":118},[559],{"type":22,"tag":78,"props":560,"children":561},{"emptyLinePlaceholder":122},[562],{"type":27,"value":125},{"type":22,"tag":78,"props":564,"children":565},{"class":80,"line":128},[566,570,574,578,582,586,590,594],{"type":22,"tag":78,"props":567,"children":568},{"style":85},[569],{"type":27,"value":134},{"type":22,"tag":78,"props":571,"children":572},{"style":85},[573],{"type":27,"value":139},{"type":22,"tag":78,"props":575,"children":576},{"style":142},[577],{"type":27,"value":145},{"type":22,"tag":78,"props":579,"children":580},{"style":91},[581],{"type":27,"value":150},{"type":22,"tag":78,"props":583,"children":584},{"style":85},[585],{"type":27,"value":155},{"type":22,"tag":78,"props":587,"children":588},{"style":91},[589],{"type":27,"value":160},{"type":22,"tag":78,"props":591,"children":592},{"style":85},[593],{"type":27,"value":165},{"type":22,"tag":78,"props":595,"children":596},{"style":91},[597],{"type":27,"value":170},{"type":22,"tag":78,"props":599,"children":600},{"class":80,"line":173},[601],{"type":22,"tag":78,"props":602,"children":603},{"style":177},[604],{"type":27,"value":180},{"type":22,"tag":78,"props":606,"children":607},{"class":80,"line":183},[608,612,616,620,624,628,632,636,640,644],{"type":22,"tag":78,"props":609,"children":610},{"style":85},[611],{"type":27,"value":189},{"type":22,"tag":78,"props":613,"children":614},{"style":192},[615],{"type":27,"value":195},{"type":22,"tag":78,"props":617,"children":618},{"style":198},[619],{"type":27,"value":201},{"type":22,"tag":78,"props":621,"children":622},{"style":91},[623],{"type":27,"value":150},{"type":22,"tag":78,"props":625,"children":626},{"style":208},[627],{"type":27,"value":211},{"type":22,"tag":78,"props":629,"children":630},{"style":85},[631],{"type":27,"value":216},{"type":22,"tag":78,"props":633,"children":634},{"style":142},[635],{"type":27,"value":221},{"type":22,"tag":78,"props":637,"children":638},{"style":91},[639],{"type":27,"value":226},{"type":22,"tag":78,"props":641,"children":642},{"style":229},[643],{"type":27,"value":232},{"type":22,"tag":78,"props":645,"children":646},{"style":91},[647],{"type":27,"value":237},{"type":22,"tag":78,"props":649,"children":650},{"class":80,"line":240},[651],{"type":22,"tag":78,"props":652,"children":653},{"emptyLinePlaceholder":122},[654],{"type":27,"value":125},{"type":22,"tag":78,"props":656,"children":657},{"class":80,"line":248},[658,662],{"type":22,"tag":78,"props":659,"children":660},{"style":85},[661],{"type":27,"value":254},{"type":22,"tag":78,"props":663,"children":664},{"style":91},[665],{"type":27,"value":170},{"type":22,"tag":78,"props":667,"children":668},{"class":80,"line":261},[669,673,677,681,685,689],{"type":22,"tag":78,"props":670,"children":671},{"style":91},[672],{"type":27,"value":267},{"type":22,"tag":78,"props":674,"children":675},{"style":85},[676],{"type":27,"value":272},{"type":22,"tag":78,"props":678,"children":679},{"style":102},[680],{"type":27,"value":105},{"type":22,"tag":78,"props":682,"children":683},{"style":108},[684],{"type":27,"value":10},{"type":22,"tag":78,"props":686,"children":687},{"style":102},[688],{"type":27,"value":285},{"type":22,"tag":78,"props":690,"children":691},{"style":91},[692],{"type":27,"value":290},{"type":22,"tag":78,"props":694,"children":695},{"class":80,"line":293},[696,700,704,708,712,716],{"type":22,"tag":78,"props":697,"children":698},{"style":91},[699],{"type":27,"value":299},{"type":22,"tag":78,"props":701,"children":702},{"style":85},[703],{"type":27,"value":272},{"type":22,"tag":78,"props":705,"children":706},{"style":102},[707],{"type":27,"value":105},{"type":22,"tag":78,"props":709,"children":710},{"style":108},[711],{"type":27,"value":8},{"type":22,"tag":78,"props":713,"children":714},{"style":102},[715],{"type":27,"value":285},{"type":22,"tag":78,"props":717,"children":718},{"style":91},[719],{"type":27,"value":290},{"type":22,"tag":78,"props":721,"children":722},{"class":80,"line":322},[723,727,731,735,739,743],{"type":22,"tag":78,"props":724,"children":725},{"style":91},[726],{"type":27,"value":328},{"type":22,"tag":78,"props":728,"children":729},{"style":85},[730],{"type":27,"value":272},{"type":22,"tag":78,"props":732,"children":733},{"style":102},[734],{"type":27,"value":105},{"type":22,"tag":78,"props":736,"children":737},{"style":108},[738],{"type":27,"value":11},{"type":22,"tag":78,"props":740,"children":741},{"style":102},[742],{"type":27,"value":285},{"type":22,"tag":78,"props":744,"children":745},{"style":91},[746],{"type":27,"value":290},{"type":22,"tag":78,"props":748,"children":749},{"class":80,"line":351},[750],{"type":22,"tag":78,"props":751,"children":752},{"style":91},[753],{"type":27,"value":357},{"type":22,"tag":78,"props":755,"children":756},{"class":80,"line":360},[757,761,765,769,773,777,781],{"type":22,"tag":78,"props":758,"children":759},{"style":91},[760],{"type":27,"value":366},{"type":22,"tag":78,"props":762,"children":763},{"style":85},[764],{"type":27,"value":272},{"type":22,"tag":78,"props":766,"children":767},{"style":229},[768],{"type":27,"value":375},{"type":22,"tag":78,"props":770,"children":771},{"style":85},[772],{"type":27,"value":380},{"type":22,"tag":78,"props":774,"children":775},{"style":229},[776],{"type":27,"value":375},{"type":22,"tag":78,"props":778,"children":779},{"style":91},[780],{"type":27,"value":389},{"type":22,"tag":78,"props":782,"children":783},{"style":177},[784],{"type":27,"value":394},{"type":22,"tag":23,"props":786,"children":787},{},[788],{"type":27,"value":399},{"type":22,"tag":401,"props":790,"children":791},{},[792,796],{"type":22,"tag":405,"props":793,"children":794},{},[795],{"type":27,"value":409},{"type":22,"tag":405,"props":797,"children":798},{},[799,800,805,806],{"type":27,"value":414},{"type":22,"tag":34,"props":801,"children":803},{"className":802},[],[804],{"type":27,"value":420},{"type":27,"value":422},{"type":22,"tag":34,"props":807,"children":809},{"className":808},[],[810],{"type":27,"value":428},{"type":22,"tag":23,"props":812,"children":813},{},[814,815,820,821,826],{"type":27,"value":433},{"type":22,"tag":34,"props":816,"children":818},{"className":817},[],[819],{"type":27,"value":439},{"type":27,"value":441},{"type":22,"tag":34,"props":822,"children":824},{"className":823},[],[825],{"type":27,"value":420},{"type":27,"value":448},{"type":22,"tag":450,"props":828,"children":829},{},[830],{"type":27,"value":454},{"type":22,"tag":23,"props":832,"children":833},{},[834,835,840,841,846],{"type":27,"value":459},{"type":22,"tag":34,"props":836,"children":838},{"className":837},[],[839],{"type":27,"value":420},{"type":27,"value":422},{"type":22,"tag":34,"props":842,"children":844},{"className":843},[],[845],{"type":27,"value":428},{"type":27,"value":472},{"type":22,"tag":474,"props":848,"children":849},{},[850],{"type":27,"value":478},{"title":7,"searchDepth":118,"depth":118,"links":852},[],1742848342869]