DEV Community

Dk Usa
Dk Usa

Posted on

React.lazy + chunk errors: how to recover users stuck after a deploy

Classic React production bug: you deploy a new bundle, user has the old HTML cached in their tab, they navigate to a route → React.lazy() tries to import a chunk that no longer exists on the CDN → blank screen.
The error in the console looks like:
Failed to fetch dynamically imported module:
https://cdn.example.com/assets/Page-abc123.js

The user has no way out except hard-reload, and most don't know that.

The fix

A global error listener that catches chunk load errors and force-reloads the page with a cache-bust param:


js
const CHUNK_ERROR_PATTERNS = [
  /Loading chunk \d+ failed/i,
  /Failed to fetch dynamically imported module/i,
  /Loading CSS chunk .* failed/i,
  /Importing a module script failed/i,
];
window.addEventListener('error', (e) => {
  const msg = e?.message || '';
  if (CHUNK_ERROR_PATTERNS.some(rx => rx.test(msg))) {
    const url = new URL(window.location.href);
    url.searchParams.set('_r', String(Date.now()));
    window.location.replace(url.toString());
  }
});
Why each part matters:

Multiple patterns: different browsers throw different messages. Safari uses "Importing a module script failed", Chrome uses "Failed to fetch dynamically imported module", older Webpack builds use "Loading chunk N failed".
Case insensitive: some browsers capitalize, some don't.
Cache-bust param: ?_r=<timestamp> forces fresh index.html, which has the new chunk hashes.
replace() not assign(): doesn't add a history entry, so back button works.
Gotchas
This catches unhandledrejection too if the lazy import throws inside a promise. Add a second listener if you see misses.
Don't trigger reload more than once: add a flag to avoid loops on a network outage.
Test it: deploy a new build, open the old tab, navigate. Should auto-recover.
It's 15 lines but saved me a real percentage of users abandoning the app post-deploy.
Enter fullscreen mode Exit fullscreen mode

Top comments (0)