fix(dashboard): return 404 for stale asset paths instead of SPA fallback

The catch-all served index.html for every unmatched URL, so a request
for a stale /assets/<oldhash>.js (after a rebuild changed the chunk
hash) got HTML back. Strict module MIME checking then failed the
script load and the page rendered as a blank shell. Exclude
/assets/, /icons/, /fonts/, /brands/, and any path with a file
extension so those return a real 404 — versionCheck.handleChunkLoadError
already knows how to recover from that.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-05-08 07:59:49 -07:00
parent 9870fe061f
commit 6797cc23ba
2 changed files with 18 additions and 2 deletions

View File

@@ -1183,8 +1183,19 @@ export function createServer(store: TaskStore, options?: ServerOptions): ReturnT
});
if (!isHeadless) {
// SPA fallback
app.get("/{*splat}", (_req, res) => {
// SPA fallback. Only serve index.html for navigation requests — never for
// hashed asset URLs (/assets/*, /icons/*, /fonts/*) or any path that looks
// like a static file. Returning index.html for a missing JS chunk poisons
// the page with a text/html module script (strict MIME failure → blank
// shell on reload). A real 404 lets versionCheck detect the stale chunk
// and recover.
const STATIC_PREFIXES = ["/assets/", "/icons/", "/fonts/", "/brands/"];
app.get("/{*splat}", (req, res) => {
const path = req.path;
if (STATIC_PREFIXES.some((p) => path.startsWith(p)) || /\.[a-z0-9]+$/i.test(path)) {
res.status(404).end();
return;
}
res.sendFile(join(clientDir, "index.html"));
});
}