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

bash
Uncaught ChunkLoadError: Loading chunk 42 failed.
(error: https://example.com/js/42.abc123.js)
    at __webpack_require__.f.j (bootstrap:1)
    at bootstrap:1

The Flow That Causes This

  1. 1.User loads the app (receives main.abc123.js)
  2. 2.main.abc123.js references 42.def456.js (not loaded yet)
  3. 3.Developer deploys new version (files are now main.ghi789.js, 42.jkl012.js)
  4. 4.Old 42.def456.js is deleted from server
  5. 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

javascript
// 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

javascript
// If using service workers, detect updates
navigator.serviceWorker.addEventListener('controllerchange', () => {
  window.location.reload();
});

Fix 4: Global Error Handler

javascript
window.addEventListener('error', (event) => {
  if (event.error?.name === 'ChunkLoadError') {
    window.location.reload();
  }
});

Fix 5: Webpack Public Path Fix

javascript
// Set public path dynamically
__webpack_public_path__ = window.__webpackPublicPath__ || '/';

Fix 6: Keep Old Assets Temporarily

yaml
# 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. 1.Deploy strategy:
  2. 2.Upload new assets
  3. 3.Deploy new code
  4. 4.Wait 24 hours
  5. 5.Clean up assets older than 24 hours