diff --git a/.changeset/fn-blank-page-service-worker-assets.md b/.changeset/fn-blank-page-service-worker-assets.md
new file mode 100644
index 0000000000..19dfd36ecf
--- /dev/null
+++ b/.changeset/fn-blank-page-service-worker-assets.md
@@ -0,0 +1,5 @@
+---
+"@runfusion/fusion": patch
+---
+
+Revalidate dashboard service-worker assets before falling back to cache so rebuilt tabs cannot stay on stale bundles and render a blank page.
diff --git a/packages/dashboard/app/__tests__/pwa.test.ts b/packages/dashboard/app/__tests__/pwa.test.ts
index 45fe05fac2..09ce06fafb 100644
--- a/packages/dashboard/app/__tests__/pwa.test.ts
+++ b/packages/dashboard/app/__tests__/pwa.test.ts
@@ -194,7 +194,7 @@ describe("PWA configuration", () => {
expect(swSource).toContain('addEventListener("install"');
expect(swSource).toContain('addEventListener("fetch"');
expect(swSource).toContain('addEventListener("activate"');
- expect(swSource).toContain('const CACHE_NAME = "fusion-cache-v4";');
+ expect(swSource).toContain('const CACHE_NAME = "fusion-cache-v5";');
});
it("service worker bypasses SSE requests instead of trying to cache them", () => {
@@ -316,7 +316,7 @@ describe("PWA configuration", () => {
expect(indexHtml).toContain('');
expect(indexHtml).toContain('');
- expect(swSource).toContain('const CACHE_NAME = "fusion-cache-v4";');
+ expect(swSource).toContain('const CACHE_NAME = "fusion-cache-v5";');
});
});
});
diff --git a/packages/dashboard/app/public/sw.js b/packages/dashboard/app/public/sw.js
index 9f53c68c68..dbd20849e5 100644
--- a/packages/dashboard/app/public/sw.js
+++ b/packages/dashboard/app/public/sw.js
@@ -1,4 +1,4 @@
-const CACHE_NAME = "fusion-cache-v4";
+const CACHE_NAME = "fusion-cache-v5";
const APP_SHELL_URLS = [
"/",
"/index.html",
diff --git a/packages/dashboard/app/versionCheck.ts b/packages/dashboard/app/versionCheck.ts
index 7676c3f031..794baa1ada 100644
--- a/packages/dashboard/app/versionCheck.ts
+++ b/packages/dashboard/app/versionCheck.ts
@@ -240,7 +240,8 @@ export async function checkVersion(trigger: VersionCheckTrigger = "initial"): Pr
} catch {
// ignore
}
- if (autoReloadEnabled) {
+ const alreadyAttempted = Boolean((() => { try { return sessionStorage.getItem(RELOAD_FLAG); } catch { return null; } })());
+ if (autoReloadEnabled && !alreadyAttempted) {
setReloadedRemoteVersion(remote);
}
reloadOnce(`build version changed: ${__BUILD_VERSION__} -> ${remote}`);