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