fix(pwa): wire up manifest link + SW registration so install prompt works

The PWA was configured end-to-end in vite.config.ts and built the
manifest + service worker correctly, but neither was ever loaded by
the browser — no <link rel="manifest"> in the HTML and no script
registering the generated registerSW.js. Chrome therefore never fired
beforeinstallprompt, no install icon appeared in the URL bar, and the
hand-rolled PwaUpdatePrompt hung on navigator.serviceWorker.ready
because no SW had been registered.

Changes:
- Render pwaInfo.webManifest.linkTag into <svelte:head> in the root
  layout so Chrome finds the hashed manifest.
- Replace the hand-rolled SW-update logic in PwaUpdatePrompt with
  useRegisterSW() from virtual:pwa-register/svelte — it registers the
  worker (immediate: true) and exposes reactive needRefresh +
  updateServiceWorker stores that match registerType: 'prompt'.
- Add triple-slash refs to vite-plugin-pwa/info and /svelte in
  app.d.ts for the virtual module types.
- Set manifest.id = startUrl in @mana/shared-pwa so Chrome doesn't
  warn and keeps the install identity stable across start_url edits.
- Keep devEnabled: false and expand the comment: the 2026-04-08
  dreams mic-button bug and the /offline navigateFallback both
  misbehave when Workbox precache doesn't run under vite dev. Test
  the install flow via `pnpm build && pnpm preview` instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-04-14 14:05:49 +02:00
parent 4192a4bd9b
commit 4b2007e97c
6 changed files with 55 additions and 55 deletions

View file

@ -62,6 +62,10 @@ export function createPWAConfig(options: PWAConfigOptions): PWAConfig {
// Build manifest
const manifest: ManifestConfig = {
// Pin the app identity to the start URL. Without `id`, Chrome derives
// one from start_url and warns in DevTools; it also refuses to
// re-prompt an install if start_url ever changes.
id: startUrl,
name,
short_name: shortName,
description,

View file

@ -139,6 +139,13 @@ export interface ManifestIcon {
* Full manifest configuration
*/
export interface ManifestConfig {
/**
* Unique manifest identifier. Chrome uses this to correlate the installed
* app with its manifest across `start_url` changes. Strongly recommended
* by the spec since 2023 omitting it triggers a DevTools warning and
* can suppress the install prompt on re-installs.
*/
id: string;
name: string;
short_name: string;
description: string;