fix(client): add /l vanity route to SW denylist; name failed offline steps (F2, F3)

F2: navigateFallbackDenylist was missing the server's `l/:alias` vanity
short-link, so a top-nav to /l/<alias> after SW registration got the
index.html app shell (which has no /l route) and dead-ended on Error404
instead of the server's 302 redirect. Add /^\/l(\/|$)/ mirroring main.ts.

F3: the partial-failure branch of "make page available offline" showed a
bare generic toast; include result.failed step labels in the message per
AGENTS.md (errors must be specific), matching the catch-branch below it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
claude code agent 227
2026-06-29 00:40:42 +03:00
parent e8805b39c8
commit 411c05a9d6
2 changed files with 13 additions and 8 deletions

View File

@@ -98,9 +98,10 @@ export function NodeMenu({ node, canEdit }: NodeMenuProps) {
} else { } else {
// Partial warm — the page may still be partly usable offline, but some // Partial warm — the page may still be partly usable offline, but some
// queries failed to cache, so surface it as an error rather than a // queries failed to cache, so surface it as an error rather than a
// silent success. // silent success. Name the failed step(s) (AGENTS.md: errors must be
// specific, never a bare generic string); `result.failed` carries them.
notifications.show({ notifications.show({
message: t("Failed to make page available offline"), message: `${t("Failed to make page available offline")}: ${result.failed.join(", ")}`,
color: "red", color: "red",
}); });
} }

View File

@@ -68,18 +68,22 @@ export default defineConfig(({ mode }) => {
// segments are consistently excluded from the SPA fallback, mirroring // segments are consistently excluded from the SPA fallback, mirroring
// the runtimeCaching urlPattern regexes below. // the runtimeCaching urlPattern regexes below.
// //
// `/share`, `/mcp`, and `/robots.txt` mirror the server static-serve // `/share`, `/mcp`, `/l`, and `/robots.txt` mirror the server
// exclude list (apps/server/src/main.ts setGlobalPrefix `exclude`): // static-serve exclude list (apps/server/src/main.ts setGlobalPrefix
// robots.txt, the SEO/OG/analytics-injected public share HTML, and the // `exclude`): robots.txt, the SEO/OG/analytics-injected public share
// embedded MCP endpoint are served by server controllers, so the SW must // HTML, the embedded MCP endpoint, and the `l/:alias` vanity short-link
// never shadow them with the precached index.html app shell (doing so // (a server 302 to a share page) are served by server controllers, so
// would break SEO and MCP). // the SW must never shadow them with the precached index.html app shell.
// For `/l/:alias` the client router has NO matching route, so serving
// the app shell would dead-end on Error404 and break the public link;
// it must reach the server to perform the redirect.
navigateFallbackDenylist: [ navigateFallbackDenylist: [
/^\/api(\/|$)/, /^\/api(\/|$)/,
/^\/collab(\/|$)/, /^\/collab(\/|$)/,
/^\/socket\.io(\/|$)/, /^\/socket\.io(\/|$)/,
/^\/share(\/|$)/, /^\/share(\/|$)/,
/^\/mcp(\/|$)/, /^\/mcp(\/|$)/,
/^\/l(\/|$)/,
/^\/robots\.txt$/, /^\/robots\.txt$/,
], ],
cleanupOutdatedCaches: true, cleanupOutdatedCaches: true,