Keep only the app page as the app page (#396)

The service worker answers app routes from its kept page (#395), and it
kept whatever the mount's root returned at install and whatever HTML a
navigation returned. Where the root is not the app -- demo.ihasmail.com
puts its landing page there -- a returning visitor got the landing page on
every route.

The kept page is now only ever the app page, recognised by the asset list
the build writes into it: install fetches /mail instead of /, a
navigation's page is kept only if it is the app's, and a foreign page left
by the earlier worker is dropped when this one activates. Only the app's
own routes are answered from it; the root and any page in front of the app
go to the network. The reload for a new build primes the kept page from
/mail for the same reason.
This commit is contained in:
jcoffey
2026-09-16 15:07:45 -07:00
committed by GitHub
parent 82dc877fe1
commit 2740129c6a
2 changed files with 44 additions and 7 deletions
+4 -1
View File
@@ -108,9 +108,12 @@ async function check(): Promise<boolean> {
async function primeShell(): Promise<void> {
if (!("caches" in window) || !navigator.serviceWorker?.controller) return;
try {
const res = await fetch(withBase("/"), { credentials: "same-origin", cache: "no-store" });
// An app route rather than the root: the root can be a page in front of
// the app (the demo's landing page is), and only the app page may be kept.
const res = await fetch(withBase("/mail"), { credentials: "same-origin", cache: "no-store" });
if (!res.ok || !(res.headers.get("content-type") ?? "").startsWith("text/html")) return;
const html = await res.text();
if (!html.includes('id="ihasmail-assets"')) return;
const cache = await caches.open(SW_CACHE_NAME);
await cache.put(withBase("/"), new Response(html, { headers: { "content-type": "text/html; charset=utf-8" } }));
} catch {