The Problem
When using code splitting with dynamic imports, JavaScript chunks are loaded on demand. After a new deployment, old chunk filenames are removed from the server. Users who had the previous version loaded may try to request old chunks and get 404 errors.
Symptoms
- "Loading chunk X failed" error after deployment
- User navigates to a route and gets a 404 for a .js file
- App breaks until the user hard refreshes (Ctrl+F5)
- Error only affects users who had the app open during deployment
Real Error Message
Uncaught ChunkLoadError: Loading chunk 42 failed.
(error: https://example.com/js/42.abc123.js)
at __webpack_require__.f.j (bootstrap:1)
at bootstrap:1The Flow That Causes This
- 1.User loads the app (receives
main.abc123.js) - 2.
main.abc123.jsreferences42.def456.js(not loaded yet) - 3.Developer deploys new version (files are now
main.ghi789.js,42.jkl012.js) - 4.Old
42.def456.jsis deleted from server - 5.User navigates, app tries to load
42.def456.js-> 404!
How to Fix It
Fix 1: Catch Chunk Load Errors and Reload
```javascript // In your router or lazy import handler const lazyLoad = (importFn) => { return () => importFn().catch(err => { if (err.message.includes('Loading chunk') || err.message.includes('ChunkLoadError')) { // Force reload to get new version window.location.reload(); } throw err; }); };
// Usage in React Router { path: '/dashboard', component: lazyLoad(() => import('./Dashboard')) } ```
Fix 2: Version Check on Navigation
// Store build version in window.__BUILD_VERSION__
// Check on each navigation
router.beforeEach(async (to, from) => {
if (window.__BUILD_VERSION__ !== window.__CURRENT_VERSION__) {
window.location.reload();
return false;
}
});Fix 3: Service Worker Update Detection
// If using service workers, detect updates
navigator.serviceWorker.addEventListener('controllerchange', () => {
window.location.reload();
});Fix 4: Global Error Handler
window.addEventListener('error', (event) => {
if (event.error?.name === 'ChunkLoadError') {
window.location.reload();
}
});Fix 5: Webpack Public Path Fix
// Set public path dynamically
__webpack_public_path__ = window.__webpackPublicPath__ || '/';Fix 6: Keep Old Assets Temporarily
# In your deployment pipeline, do NOT immediately delete old assets
# Keep previous version's assets for at least 24 hours
# This gives users with stale pages time to refresh- 1.Deploy strategy:
- 2.Upload new assets
- 3.Deploy new code
- 4.Wait 24 hours
- 5.Clean up assets older than 24 hours