diff --git a/src/main.tsx b/src/main.tsx index b733dfa..3079840 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -76,6 +76,40 @@ import '@fontsource/barlow-condensed/700.css'; })(); +/** + * STALE-DEPLOY SELF-HEAL + * + * Deploys replace hashed chunk filenames and delete the old ones. A tab that + * was already open still holds the previous manifest, so navigating to a lazy + * route loads a chunk that no longer exists (404) and the error boundary shows + * "THIS PAGE SLAMMED". Vite emits `vite:preloadError` for exactly this case. + * + * Reload once to pick up the new assets. The timestamp guard prevents a reload + * loop if a build is genuinely broken (the error boundary will show instead). + */ +(function recoverFromStaleChunks() { + const KEY = 'skatespots:chunk-reload-at'; + const reload = () => { + try { + const last = Number(sessionStorage.getItem(KEY) || 0); + if (Date.now() - last < 15000) return; // already reloaded recently — don't loop + sessionStorage.setItem(KEY, String(Date.now())); + } catch { + /* sessionStorage unavailable — fall through and reload anyway */ + } + window.location.reload(); + }; + + window.addEventListener('vite:preloadError', reload); + window.addEventListener('unhandledrejection', (e) => { + const msg = String((e as PromiseRejectionEvent).reason?.message ?? ''); + if (/dynamically imported module|Importing a module script failed|Loading chunk/i.test(msg)) { + reload(); + } + }); +})(); + + createRoot(document.getElementById("root")!).render(