Files
Jyotisha/frontend/src/components/stale-client-recovery.tsx
T
Jesse_ChenandCursor 50e1a4aca5 fix(web): reload stale clients instead of spinning after a release
Homepage bootstrap never escaped the loading shell when a new web image changed chunk hashes. Stamp deploymentId, stop caching chat HTML, and hard-reload failed chunk loads once.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-21 10:29:43 +08:00

51 lines
1.6 KiB
TypeScript

"use client";
import { useEffect } from "react";
import {
consumeStaleClientReload,
isChunkLoadFailure,
shouldReloadFrozenBootstrap,
} from "@/lib/stale-client-recovery";
function reloadIfStale() {
try {
if (!consumeStaleClientReload(sessionStorage)) return;
} catch {
return;
}
window.location.reload();
}
export function StaleClientRecovery() {
useEffect(() => {
const onError = (event: ErrorEvent) => {
const message = `${event.message} ${event.filename ?? ""} ${event.error instanceof Error ? event.error.message : ""}`;
if (isChunkLoadFailure(message)) reloadIfStale();
};
const onRejection = (event: PromiseRejectionEvent) => {
const reason = event.reason;
const message = reason instanceof Error ? reason.message : String(reason ?? "");
if (isChunkLoadFailure(message)) reloadIfStale();
};
const onPageShow = (event: PageTransitionEvent) => {
if (shouldReloadFrozenBootstrap({
persisted: event.persisted,
loadingBusy: Boolean(document.querySelector('main.app-loading[aria-busy="true"]')),
loadingError: Boolean(document.querySelector("main.app-loading-error")),
})) {
reloadIfStale();
}
};
window.addEventListener("error", onError);
window.addEventListener("unhandledrejection", onRejection);
window.addEventListener("pageshow", onPageShow);
return () => {
window.removeEventListener("error", onError);
window.removeEventListener("unhandledrejection", onRejection);
window.removeEventListener("pageshow", onPageShow);
};
}, []);
return null;
}