[{"data":1,"prerenderedAt":334},["ShallowReactive",2],{"i-base:v-logo":3,"i-lucide:user":8,"i-lucide:folder-kanban":11,"i-lucide:heart":13,"i-lucide:file-text":15,"i-lucide:sun":17,"i-lucide:github":19,"i-lucide:twitter":22,"i-lucide:linkedin":24,"i-simple-icons:reddit":26,"i-lucide:globe":28,"article-til-workers-cache-nitro-passthrough":30,"articles-all":287,"i-lucide:arrow-left":332},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":7},0,512,false,"\u003Cg fill=\"currentColor\">\u003Cg transform=\"translate(0,512) scale(0.1,-0.1)\">\n    \u003Cpath d=\"M2866 3193 c-203 -209 -341 -393 -541 -718 -57 -93 -198 -309 -212 -325 -9 -9 -22 26 -28 75 -4 27 -8 61 -10 75 -2 14 -7 70 -10 125 -21 363 -72 541 -187 656 -30 30 -54 64 -56 78 -7 55 -65 113 -130 130 -21 6 -34 1 -62 -23 -64 -57 -86 -84 -97 -119 -12 -41 -9 -201 7 -349 6 -57 12 -204 12 -327 0 -191 2 -232 18 -270 10 -27 20 -89 24 -148 5 -92 21 -182 84 -478 12 -56 30 -105 46 -129 14 -21 27 -48 27 -60 1 -12 3 -39 4 -61 1 -23 8 -41 16 -44 8 -2 39 -31 69 -63 66 -72 98 -90 159 -91 133 -1 245 118 254 271 4 67 7 74 45 114 22 24 50 55 61 70 33 42 81 138 81 162 0 12 21 44 50 74 27 28 63 80 80 114 57 114 131 230 244 378 48 64 213 266 249 305 78 85 167 207 167 230 0 14 11 47 23 73 34 67 29 133 -20 252 l-38 95 -50 6 c-28 3 -67 13 -87 22 -21 10 -47 17 -58 17 -13 0 -62 -43 -134 -117z\"\u002F>\n    \u003Cpath d=\"M3070 1649 c-30 -44 -76 -96 -102 -115 -27 -20 -48 -40 -48 -45 0 -5 8 -21 17 -36 17 -25 17 -27 -5 -41 l-22 -14 30 -35 c17 -18 30 -39 30 -47 0 -36 34 -118 58 -140 102 -92 120 -104 159 -100 108 10 153 24 153 49 0 7 27 28 59 45 62 33 92 74 90 121 -1 13 10 57 25 97 32 87 33 90 17 165 -15 70 -24 75 -177 111 -159 38 -194 48 -200 57 -12 21 -32 4 -84 -72z\"\u002F>\n  \u003C\u002Fg>\u003C\u002Fg>",{"left":4,"top":4,"width":9,"height":9,"rotate":4,"vFlip":6,"hFlip":6,"body":10},24,"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2\"\u002F>\u003Ccircle cx=\"12\" cy=\"7\" r=\"4\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":9,"height":9,"rotate":4,"vFlip":6,"hFlip":6,"body":12},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2m4-10v4m4-4v2m4-2v6\"\u002F>",{"left":4,"top":4,"width":9,"height":9,"rotate":4,"vFlip":6,"hFlip":6,"body":14},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M2 9.5a5.5 5.5 0 0 1 9.591-3.676a.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5\"\u002F>",{"left":4,"top":4,"width":9,"height":9,"rotate":4,"vFlip":6,"hFlip":6,"body":16},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\"\u002F>\u003Cpath d=\"M14 2v5a1 1 0 0 0 1 1h5M10 9H8m8 4H8m8 4H8\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":9,"height":9,"rotate":4,"vFlip":6,"hFlip":6,"body":18},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"4\"\u002F>\u003Cpath d=\"M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32l1.41 1.41M2 12h2m16 0h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":9,"height":9,"rotate":4,"vFlip":6,"hFlip":6,"body":20,"hidden":21},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5c.08-1.25-.27-2.48-1-3.5c.28-1.15.28-2.35 0-3.5c0 0-1 0-3 1.5c-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.4 5.4 0 0 0 4 9c0 3.5 3 5.5 6 5.5c-.39.49-.68 1.05-.85 1.65S8.93 17.38 9 18v4\"\u002F>\u003Cpath d=\"M9 18c-4.51 2-5-2-7-2\"\u002F>\u003C\u002Fg>",true,{"left":4,"top":4,"width":9,"height":9,"rotate":4,"vFlip":6,"hFlip":6,"body":23,"hidden":21},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M22 4s-.7 2.1-2 3.4c1.6 10-9.4 17.3-18 11.6c2.2.1 4.4-.6 6-2C3 15.5.5 9.6 3 5c2.2 2.6 5.6 4.1 9 4c-.9-4.2 4-6.6 7-3.8c1.1 0 3-1.2 3-1.2\"\u002F>",{"left":4,"top":4,"width":9,"height":9,"rotate":4,"vFlip":6,"hFlip":6,"body":25,"hidden":21},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2a2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6M2 9h4v12H2z\"\u002F>\u003Ccircle cx=\"4\" cy=\"4\" r=\"2\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":9,"height":9,"rotate":4,"vFlip":6,"hFlip":6,"body":27},"\u003Cpath fill=\"currentColor\" d=\"M12 0C5.373 0 0 5.373 0 12c0 3.314 1.343 6.314 3.515 8.485l-2.286 2.286A.72.72 0 0 0 1.738 24H12c6.627 0 12-5.373 12-12S18.627 0 12 0m4.388 3.199a1.999 1.999 0 1 1-1.947 2.46v.002a2.37 2.37 0 0 0-2.032 2.341v.007c1.776.067 3.4.567 4.686 1.363a2.802 2.802 0 1 1 2.908 4.753c-.088 3.256-3.637 5.876-7.997 5.876c-4.361 0-7.905-2.617-7.998-5.87a2.8 2.8 0 0 1 1.189-5.34c.645 0 1.239.218 1.712.585c1.275-.79 2.881-1.291 4.64-1.365v-.01a3.23 3.23 0 0 1 2.88-3.207a2 2 0 0 1 1.959-1.595m-8.085 8.376c-.784 0-1.459.78-1.506 1.797s.64 1.429 1.426 1.429s1.371-.369 1.418-1.385s-.553-1.841-1.338-1.841m7.406 0c-.786 0-1.385.824-1.338 1.841s.634 1.385 1.418 1.385c.785 0 1.473-.413 1.426-1.429c-.046-1.017-.721-1.797-1.506-1.797m-3.703 4.013c-.974 0-1.907.048-2.77.135a.222.222 0 0 0-.183.305a3.2 3.2 0 0 0 2.953 1.964a3.2 3.2 0 0 0 2.953-1.964a.222.222 0 0 0-.184-.305a28 28 0 0 0-2.769-.135\"\u002F>",{"left":4,"top":4,"width":9,"height":9,"rotate":4,"vFlip":6,"hFlip":6,"body":29},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"10\"\u002F>\u003Cpath d=\"M12 2a14.5 14.5 0 0 0 0 20a14.5 14.5 0 0 0 0-20M2 12h20\"\u002F>\u003C\u002Fg>",{"id":31,"title":32,"body":33,"category":272,"date":273,"description":274,"extension":275,"image":276,"meta":277,"navigation":21,"path":278,"seo":279,"status":280,"stem":281,"tags":282,"updatedAt":276,"__hash__":286},"articles\u002Farticles\u002F2.til-workers-cache-nitro-passthrough.md","TIL: Enabling Workers Cache through Nitro without a native option",{"type":34,"value":35,"toc":268},"minimark",[36,57,68,73,97,100,218,232,236,253,264],[37,38,39,40,47,48,52,53,56],"p",{},"Cloudflare shipped ",[41,42,46],"a",{"href":43,"rel":44},"https:\u002F\u002Fblog.cloudflare.com\u002Fworkers-cache\u002F",[45],"nofollow","Workers Cache"," to GA in July 2026: a tiered, regional cache that sits in front of a Worker and is driven entirely by standard ",[49,50,51],"code",{},"Cache-Control"," headers. Cache hits are billed at the request rate with no CPU charge, and it works on ",[49,54,55],{},"workers.dev",", preview URLs, and service bindings.",[37,58,59,60,63,64,67],{},"The catch: when you deploy a Nuxt app through Nitro's ",[49,61,62],{},"cloudflare_module"," preset, there is no ",[49,65,66],{},"nitro.cloudflare.cache"," option. I went looking for one and it does not exist.",[69,70,72],"h2",{"id":71},"the-one-thing-worth-knowing","The one thing worth knowing",[37,74,75,76,79,80,87,88,91,92,96],{},"Nitro builds the final ",[49,77,78],{},"wrangler.json"," by deep-merging config with ",[41,81,84],{"href":82,"rel":83},"https:\u002F\u002Fgithub.com\u002Funjs\u002Fdefu",[45],[49,85,86],{},"defu",", and the ",[49,89,90],{},"wrangler"," block has ",[93,94,95],"strong",{},"no allowlist",". Any key you put there is passed straight through to the generated config.",[37,98,99],{},"So the entire setup is one nested block:",[101,102,107],"pre",{"className":103,"code":104,"language":105,"meta":106,"style":106},"language-ts shiki shiki-themes github-dark github-dark github-light","export default defineNuxtConfig({\n  nitro: {\n    preset: 'cloudflare_module',\n    cloudflare: {\n      deployConfig: true,\n      wrangler: {\n        cache: {\n          enabled: true,\n        },\n      },\n    },\n  },\n});\n","ts","",[49,108,109,129,135,148,154,166,172,178,188,194,200,206,212],{"__ignoreMap":106},[110,111,114,118,121,125],"span",{"class":112,"line":113},"line",1,[110,115,117],{"class":116},"s6ubI","export",[110,119,120],{"class":116}," default",[110,122,124],{"class":123},"s5n6i"," defineNuxtConfig",[110,126,128],{"class":127},"sAvwS","({\n",[110,130,132],{"class":112,"line":131},2,[110,133,134],{"class":127},"  nitro: {\n",[110,136,138,141,145],{"class":112,"line":137},3,[110,139,140],{"class":127},"    preset: ",[110,142,144],{"class":143},"s4Y1p","'cloudflare_module'",[110,146,147],{"class":127},",\n",[110,149,151],{"class":112,"line":150},4,[110,152,153],{"class":127},"    cloudflare: {\n",[110,155,157,160,164],{"class":112,"line":156},5,[110,158,159],{"class":127},"      deployConfig: ",[110,161,163],{"class":162},"sXWYR","true",[110,165,147],{"class":127},[110,167,169],{"class":112,"line":168},6,[110,170,171],{"class":127},"      wrangler: {\n",[110,173,175],{"class":112,"line":174},7,[110,176,177],{"class":127},"        cache: {\n",[110,179,181,184,186],{"class":112,"line":180},8,[110,182,183],{"class":127},"          enabled: ",[110,185,163],{"class":162},[110,187,147],{"class":127},[110,189,191],{"class":112,"line":190},9,[110,192,193],{"class":127},"        },\n",[110,195,197],{"class":112,"line":196},10,[110,198,199],{"class":127},"      },\n",[110,201,203],{"class":112,"line":202},11,[110,204,205],{"class":127},"    },\n",[110,207,209],{"class":112,"line":208},12,[110,210,211],{"class":127},"  },\n",[110,213,215],{"class":112,"line":214},13,[110,216,217],{"class":127},"});\n",[37,219,220,221,224,225,228,229,231],{},"That generates ",[49,222,223],{},".output\u002Fserver\u002Fwrangler.json"," with ",[49,226,227],{},"cache"," included. Add ",[49,230,51],{}," headers to the responses you want cached and you are done.",[69,233,235],{"id":234},"two-things-that-will-bite-you","Two things that will bite you",[37,237,238,239,242,243,245,246,248,249,252],{},"Workers Cache is ",[93,240,241],{},"Worker-only",". Cloudflare Pages has an explicit allowlist of supported config fields, and ",[49,244,227],{}," is not on it. Deploying a Pages project with a ",[49,247,227],{}," key fails outright with ",[49,250,251],{},"Configuration file for Pages projects does not support \"cache\"",". This is one more reason the Pages-to-Workers migration is worth doing.",[37,254,255,256,259,260,263],{},"Second, mind your Wrangler version. The basic ",[49,257,258],{},"cache: { enabled: true }"," block landed in Wrangler 4.89.0. Per-entrypoint cache control through the ",[49,261,262],{},"exports"," map needs 4.107.0 or newer. On older Wrangler the extra keys are silently dropped with a warning rather than an error, so it looks like it worked when it did not.",[265,266,267],"style",{},"html pre.shiki code .s6ubI, html code.shiki .s6ubI{--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-light:#D73A49}html pre.shiki code .s5n6i, html code.shiki .s5n6i{--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-light:#6F42C1}html pre.shiki code .sAvwS, html code.shiki .sAvwS{--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-light:#24292E}html pre.shiki code .s4Y1p, html code.shiki .s4Y1p{--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-light:#032F62}html pre.shiki code .sXWYR, html code.shiki .sXWYR{--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-light:#005CC5}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 .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);}",{"title":106,"searchDepth":131,"depth":131,"links":269},[270,271],{"id":71,"depth":131,"text":72},{"id":234,"depth":131,"text":235},"cloudflare","2026-07-06T14:30:00.000+05:30","Nitro forwards arbitrary keys into the generated wrangler config, so you can turn on Cloudflare Workers Cache with a single line even though there is no dedicated Nitro option for it.","md",null,{"position":131},"\u002Farticles\u002Ftil-workers-cache-nitro-passthrough",{"title":32,"description":274},"published","articles\u002F2.til-workers-cache-nitro-passthrough",[272,283,284,285],"workers","nitro","nuxt","Cwqi9AiQz1IWmETeiUeCcmRHmjKCYvjswrDucWBG_NA",[288,297,305,312,321,323],{"path":289,"title":290,"description":291,"date":292,"updatedAt":276,"category":285,"tags":293,"image":276,"status":280},"\u002Farticles\u002Ftil-shiki-multitheme-code-block-background","TIL: Shiki multi-theme highlighting does not switch the code-block background","Shiki multi-theme mode swaps token colours per colour scheme but leaves the pre background variable empty, so light-theme text can land on a dark block. You have to theme the container yourself.","2026-07-07T02:30:00.000+05:30",[285,294,295,296],"shiki","nuxt-content","dark-mode",{"path":298,"title":299,"description":300,"date":301,"updatedAt":276,"category":272,"tags":302,"image":276,"status":280},"\u002Farticles\u002Fdynamic-og-images-on-cloudflare-workers","Generating dynamic Open Graph images on Cloudflare Workers","Rendering per-page and per-article social cards at the edge with Satori and @cf-wasm\u002Fog: how the route works, what Satori refuses to render, and the cold-versus-warm numbers.","2026-07-06T22:00:00.000+05:30",[272,283,303,304,285],"open-graph","satori",{"path":306,"title":307,"description":308,"date":309,"updatedAt":276,"category":272,"tags":310,"image":276,"status":280},"\u002Farticles\u002Fmigrating-a-nuxt-site-from-cloudflare-pages-to-workers","Migrating a Nuxt site from Cloudflare Pages to Workers","The full path from the cloudflare-pages preset to a cloudflare_module Worker: the config changes, the custom-domain cutover that no deploy step handles for you, and the gotchas that only show up in CI.","2026-07-06T21:00:00.000+05:30",[272,283,285,284,311],"devops",{"path":313,"title":314,"description":315,"date":316,"updatedAt":276,"category":317,"tags":318,"image":276,"status":280},"\u002Farticles\u002Ftil-tailwind-v4-webkit-mask-prefix","TIL: Tailwind v4 mask utilities need the webkit prefix in plain CSS","Porting a Tailwind mask-composite utility to scoped CSS quietly breaks in Chrome and Safari unless you also write the -webkit-mask-* properties, because Tailwind was emitting them for you.","2026-07-06T20:15:00.000+05:30","css",[319,317,320],"tailwind","webkit",{"path":278,"title":32,"description":274,"date":273,"updatedAt":276,"category":272,"tags":322,"image":276,"status":280},[272,283,284,285],{"path":324,"title":325,"description":326,"date":327,"updatedAt":276,"category":328,"tags":329,"image":276,"status":280},"\u002Farticles\u002Fbuild-and-publish-vue-3-components-using-rollup","Build & Publish Vue 3 Components using Rollup.js","Let's build a reusable Vue 3 component using rollup","2022-07-04T16:20:09.000+05:30","vue",[330,331],"vue 3","rollup",{"left":4,"top":4,"width":9,"height":9,"rotate":4,"vFlip":6,"hFlip":6,"body":333},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m12 19l-7-7l7-7m7 7H5\"\u002F>",1783374868970]