[{"data":1,"prerenderedAt":512},["ShallowReactive",2],{"navigation":3,"/blog/postmortem-nuxt-cloudflare-chunk-error":154,"surround-postmortem-nuxt-cloudflare-chunk-error":501},[4],{"title":5,"path":6,"stem":7,"children":8,"page":153},"Blog","/blog","blog",[9,13,17,21,25,29,33,37,41,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,129,133,137,141,145,149],{"title":10,"path":11,"stem":12},"How to Increase Free Tier Memory on AWS EC2","/blog/aws-ec2-ram","blog/aws-ec2-ram",{"title":14,"path":15,"stem":16},"Blooper: The Disappearing Cloudflare Variables","/blog/blooper-cloudflare-env-vars","blog/blooper-cloudflare-env-vars",{"title":18,"path":19,"stem":20},"Blooper: Hardcoded Content Links cause 404s","/blog/blooper-hardcoded-nuxt-content-links","blog/blooper-hardcoded-nuxt-content-links",{"title":22,"path":23,"stem":24},"Blooper: The Invisible SEO","/blog/blooper-nuxt-seo-env","blog/blooper-nuxt-seo-env",{"title":26,"path":27,"stem":28},"Blooper: The SSR Crash of Doom","/blog/blooper-ssr-feedback-form","blog/blooper-ssr-feedback-form",{"title":30,"path":31,"stem":32},"Blooper: The YouTube Crawl Budget Killer","/blog/blooper-video-crawl-budget","blog/blooper-video-crawl-budget",{"title":34,"path":35,"stem":36},"Blooper: PWA Redirecting SPA Routes","/blog/blooper-vite-pwa-ssr-redirects","blog/blooper-vite-pwa-ssr-redirects",{"title":38,"path":39,"stem":40},"Git Branching in 2026: Code State, Environment Isolation, and Modern CD","/blog/branch-theater-staging-branches","blog/branch-theater-staging-branches",{"title":42,"path":43,"stem":44},"The Developer's Guide to Avoiding Cloud Billing Traps in 2026","/blog/cloud-billing-traps-2026","blog/cloud-billing-traps-2026",{"title":46,"path":47,"stem":48},"Disk Management in Linux","/blog/disk-management-in-linux","blog/disk-management-in-linux",{"title":50,"path":51,"stem":52},"Docker Devtools Stage | Powerlevel, OhMyZSH, tmux, fuzzy finder, autocomplete etc","/blog/docker-devtools","blog/docker-devtools",{"title":54,"path":55,"stem":56},"Docker container | Resolving Permission Denied Woes: A Decade-Long Struggle Unraveled","/blog/docker-non-root-user-perms","blog/docker-non-root-user-perms",{"title":58,"path":59,"stem":60},"The Ultimate Guide to Free Tier Hosting Platforms (Serverless & Containers)","/blog/free-hosting-platforms-guide","blog/free-hosting-platforms-guide",{"title":62,"path":63,"stem":64},"Git commands | underrated","/blog/git-commands-underrated","blog/git-commands-underrated",{"title":66,"path":67,"stem":68},"Journey: Taming Edge Caching and KV Storage","/blog/journey-github-streak-caching","blog/journey-github-streak-caching",{"title":70,"path":71,"stem":72},"Kubernetes Cluster Setup Guide","/blog/k8s-setup","blog/k8s-setup",{"title":74,"path":75,"stem":76},"Linux WiFi Drivers","/blog/linux-wifi-drivers","blog/linux-wifi-drivers",{"title":78,"path":79,"stem":80},"4 Common Routing Traps When Migrating to Nuxt i18n","/blog/nuxt-i18n-routing","blog/nuxt-i18n-routing",{"title":82,"path":83,"stem":84},"Patch the CVE, Don't Trigger an Accidental Refactor: Surviving PHP2Shell on Docker","/blog/patching-php2shell-docker-playbook","blog/patching-php2shell-docker-playbook",{"title":86,"path":87,"stem":88},"pfSense basic firewall setup","/blog/pfsense-basic-firewall-setup","blog/pfsense-basic-firewall-setup",{"title":90,"path":91,"stem":92},"pfSense Quickstart","/blog/pfsense-quickstart","blog/pfsense-quickstart",{"title":94,"path":95,"stem":96},"Postmortem: Cloudflare Worker Missing Dependency on Deploy","/blog/postmortem-cloudflare-worker-dependency-deploy","blog/postmortem-cloudflare-worker-dependency-deploy",{"title":98,"path":99,"stem":100},"Postmortem: Serverless HTTP Driver Transaction Failures","/blog/postmortem-neon-http-transactions","blog/postmortem-neon-http-transactions",{"title":102,"path":103,"stem":104},"Postmortem: The Ghost in the Chrome Cache (Nuxt & Cloudflare Pages)","/blog/postmortem-nuxt-cloudflare-chunk-error","blog/postmortem-nuxt-cloudflare-chunk-error",{"title":106,"path":107,"stem":108},"Postmortem: Nuxt Content 404s on Staging Deployments","/blog/postmortem-nuxt-content-404-staging","blog/postmortem-nuxt-content-404-staging",{"title":110,"path":111,"stem":112},"Postmortem: 500 Internal Server Error on ISR Routes","/blog/postmortem-nuxt-content-payload-extraction","blog/postmortem-nuxt-content-payload-extraction",{"title":114,"path":115,"stem":116},"Post-Mortem: Intrusive Database Driver Refactoring","/blog/postmortem-proxy-re-architecting","blog/postmortem-proxy-re-architecting",{"title":118,"path":119,"stem":120},"Post-Mortem: Cloudflare Worker Connection Hang & Resilient DB Fallbacks","/blog/postmortem-worker-db-connection-hang","blog/postmortem-worker-db-connection-hang",{"title":122,"path":123,"stem":124},"Pro Tip: Sandboxing Cloudflare Workers for AI Agents","/blog/pro-tip-wrangler-local-dev-trick","blog/pro-tip-wrangler-local-dev-trick",{"title":126,"path":127,"stem":128},"Proxmox DNS Management","/blog/proxmox-dns","blog/proxmox-dns",{"title":130,"path":131,"stem":132},"Proxmox Recovery","/blog/proxmox-recovery","blog/proxmox-recovery",{"title":134,"path":135,"stem":136},"Proxmox WiFi Connection Story","/blog/proxmox-wifi","blog/proxmox-wifi",{"title":138,"path":139,"stem":140},"roadauth-rails api jwt cors","/blog/rodauth-jwt","blog/rodauth-jwt",{"title":142,"path":143,"stem":144},"SOCKS5 Proxy Quickstart","/blog/sock5-proxy","blog/sock5-proxy",{"title":146,"path":147,"stem":148},"tmux status bar toggle","/blog/tmux-status","blog/tmux-status",{"title":150,"path":151,"stem":152},"UFW - Cheatsheet","/blog/ufw-cheatsheet","blog/ufw-cheatsheet",false,{"id":155,"title":102,"authors":156,"badge":162,"body":164,"date":489,"description":490,"extension":491,"image":492,"imageComponent":493,"meta":495,"navigation":496,"path":103,"pinned":153,"seo":497,"seoImage":498,"stem":104,"__hash__":500},"posts/blog/postmortem-nuxt-cloudflare-chunk-error.md",[157],{"name":158,"to":159,"avatar":160},"Rahul Dhole","/",{"src":161},"/profile.png",{"label":163},"Postmortem",{"type":165,"value":166,"toc":479},"minimark",[167,172,181,184,194,197,211,217,225,228,232,235,257,268,273,280,301,308,319,328,345,347,351,354,358,364,375,379,382,389,465,475],[168,169,171],"h2",{"id":170},"the-incident","The Incident",[173,174,175,176,180],"p",{},"It was supposed to be a routine deployment. I wrote a new blog post, pushed it to ",[177,178,179],"code",{},"main",", and watched Cloudflare Pages build and deploy the Nuxt 3 site successfully. Everything looked green.",[173,182,183],{},"Then, I opened the site in Chrome, clicked a link, and the page crashed with this infamous error:",[185,186,192],"pre",{"className":187,"code":189,"language":190,"meta":191},[188],"language-text","[nuxt] error caught during app initialization\nTypeError: Failed to fetch dynamically imported module: https://rahuldhole.com/_nuxt/Dg6KwZeV.js\n","text","",[177,193,189],{"__ignoreMap":191},[173,195,196],{},"\"No problem,\" I thought. \"Just a stale chunk. I'll do a hard reload.\"",[173,198,199,200,203,204,208,209],{},"I hit ",[177,201,202],{},"Cmd+Shift+R",". ",[205,206,207],"strong",{},"It still crashed.","\nI opened an Incognito window. ",[205,210,207],{},[173,212,213,214],{},"Then, out of sheer desperation, I opened the site in Firefox. ",[205,215,216],{},"It worked perfectly.",[173,218,219,220,224],{},"Why would a missing JavaScript chunk error happen ",[221,222,223],"em",{},"only"," in Chrome, survive a hard reload, and persist even in Incognito mode?",[226,227],"hr",{},[168,229,231],{"id":230},"the-investigation","The Investigation",[173,233,234],{},"Initially, my thoughts went to the usual suspects:",[236,237,238,245,251],"ol",{},[239,240,241,244],"li",{},[205,242,243],{},"A rogue Service Worker?"," I didn't have one installed.",[239,246,247,250],{},[205,248,249],{},"A corrupted Nuxt build?"," A local build verified everything was compiling perfectly.",[239,252,253,256],{},[205,254,255],{},"A Chrome extension?"," Incognito mode ruled that out.",[173,258,259,260,263,264,267],{},"The fact that Firefox was getting the fresh files while Chrome was getting an old ",[177,261,262],{},"index.html"," (which was asking for a deleted ",[177,265,266],{},".js"," chunk) meant this had to be an edge caching issue. But why was Cloudflare treating Chrome differently than Firefox?",[269,270,272],"h3",{"id":271},"the-culprit-accept-encoding","The Culprit: Accept-Encoding",[173,274,275,276,279],{},"The breakthrough came when looking at how modern browsers request files, specifically the ",[177,277,278],{},"Accept-Encoding"," header.",[281,282,283,292],"ul",{},[239,284,285,288,289],{},[205,286,287],{},"Chrome"," (and most Chromium browsers) asks for: ",[177,290,291],{},"gzip, deflate, br, zstd",[239,293,294,297,298],{},[205,295,296],{},"Firefox"," asks for: ",[177,299,300],{},"gzip, deflate, br",[173,302,303,304,307],{},"Cloudflare is smart. Too smart, sometimes. It caches responses ",[221,305,306],{},"separately"," based on the compression format.",[173,309,310,311,314,315,318],{},"When my deployment finished, Cloudflare automatically purged its edge cache. However, due to an eventual consistency hiccup on the edge node nearest to me, the ",[177,312,313],{},"br"," (Brotli) cache key was successfully purged, while the ",[177,316,317],{},"zstd"," (Zstandard) cache key got stuck.",[173,320,321,322,324,325,327],{},"So when Firefox visited the site, Cloudflare saw a cache miss for ",[177,323,313],{},", fetched the fresh ",[177,326,262],{}," from the origin, and loaded the site perfectly.",[173,329,330,331,333,334,337,338,340,341,344],{},"But when Chrome visited the site, Cloudflare saw a cache hit for ",[177,332,317],{},", and happily served up the ",[221,335,336],{},"old"," ",[177,339,262],{}," from before the deployment. That old HTML file told Chrome to download ",[177,342,343],{},"Dg6KwZeV.js","—a file that had already been deleted from the server. Boom. Crash.",[226,346],{},[168,348,350],{"id":349},"the-solution","The Solution",[173,352,353],{},"There are two steps to fixing this and ensuring it never impacts users again.",[269,355,357],{"id":356},"_1-the-immediate-fix-purge-everything","1. The Immediate Fix: Purge Everything",[173,359,360,361,363],{},"A hard reload in your browser doesn't change the ",[177,362,278],{}," header, so you just keep hitting the same stuck cache key on the edge node.",[173,365,366,367,370,371,374],{},"The only way to forcefully break the cycle is to log into the Cloudflare Dashboard, go to ",[205,368,369],{},"Caching > Configuration",", and hit ",[205,372,373],{},"\"Purge Everything\"",". Within 60 seconds, Chrome was back to normal.",[269,376,378],{"id":377},"_2-the-long-term-fix-nuxts-built-in-safety-net","2. The Long-Term Fix: Nuxt's Built-in Safety Net",[173,380,381],{},"You can't expect your users to purge your Cloudflare cache for you. Thankfully, the Nuxt team is well aware of these SPA chunk loading errors and built a native safeguard directly into the framework.",[173,383,384,385,388],{},"By adding this to your ",[177,386,387],{},"nuxt.config.ts",":",[185,390,394],{"className":391,"code":392,"language":393,"meta":191,"style":191},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","export default defineNuxtConfig({\n  experimental: {\n    emitRouteChunkError: 'automatic'\n  }\n})\n","typescript",[177,395,396,420,432,450,456],{"__ignoreMap":191},[397,398,401,405,408,412,416],"span",{"class":399,"line":400},"line",1,[397,402,404],{"class":403},"s7zQu","export",[397,406,407],{"class":403}," default",[397,409,411],{"class":410},"s2Zo4"," defineNuxtConfig",[397,413,415],{"class":414},"sTEyZ","(",[397,417,419],{"class":418},"sMK4o","{\n",[397,421,423,427,429],{"class":399,"line":422},2,[397,424,426],{"class":425},"swJcz","  experimental",[397,428,388],{"class":418},[397,430,431],{"class":418}," {\n",[397,433,435,438,440,443,447],{"class":399,"line":434},3,[397,436,437],{"class":425},"    emitRouteChunkError",[397,439,388],{"class":418},[397,441,442],{"class":418}," '",[397,444,446],{"class":445},"sfazB","automatic",[397,448,449],{"class":418},"'\n",[397,451,453],{"class":399,"line":452},4,[397,454,455],{"class":418},"  }\n",[397,457,459,462],{"class":399,"line":458},5,[397,460,461],{"class":418},"}",[397,463,464],{"class":414},")\n",[173,466,467,468,471,472,474],{},"Nuxt will intercept that ",[177,469,470],{},"Failed to fetch dynamically imported module"," error. Instead of throwing a fatal crash, it will automatically force a hard reload of the window, seamlessly fetching the fresh ",[177,473,262],{}," and the correct chunks. Your users get the new site, and nobody even notices the deployment happened!",[476,477,478],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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":191,"searchDepth":422,"depth":422,"links":480},[481,482,485],{"id":170,"depth":422,"text":171},{"id":230,"depth":422,"text":231,"children":483},[484],{"id":271,"depth":434,"text":272},{"id":349,"depth":422,"text":350,"children":486},[487,488],{"id":356,"depth":434,"text":357},{"id":377,"depth":434,"text":378},"2026-08-06","How a routine Nuxt deployment led to a bizarre, Chrome-only \"Failed to fetch dynamically imported module\" crash—and the obscure Cloudflare caching quirk behind it.","md",null,{"title":494,"subtitle":470,"type":163},"INCIDENT: Chunk Load Error",{},true,{"title":102,"description":490},{"src":499},"https://placehold.co/800x400/ef4444/ffffff?text=Nuxt+Chunk+Error+Postmortem","GycffuOqrn3mCbu9lSkwbDooT1oIa8ahcVvial9ZNX8",[502,507],{"title":98,"path":99,"stem":100,"description":503,"imageComponent":504,"seoImage":505,"children":-1},"Why database transactions fail in serverless HTTP drivers and how to architect around them using compensating transactions.",{"type":163},{"src":506},"https://placehold.co/800x400/0f172a/3b82f6?text=Serverless+HTTP+Transactions",{"title":106,"path":107,"stem":108,"description":508,"imageComponent":509,"seoImage":510,"children":-1},"Debugging missing content and 404 errors when deploying Nuxt Content to Cloudflare D1.",{"type":163},{"src":511},"https://placehold.co/800x400/0f172a/3b82f6?text=Nuxt+Content+404s",1792752997593]