Skip to content

feat(app): add PWA support with service worker and update prompt#32162

Open
shoootyou wants to merge 1 commit into
anomalyco:devfrom
shoootyou:feat/pwa-support
Open

feat(app): add PWA support with service worker and update prompt#32162
shoootyou wants to merge 1 commit into
anomalyco:devfrom
shoootyou:feat/pwa-support

Conversation

@shoootyou

Copy link
Copy Markdown

Supersedes #31279 (closed). That branch predates the v1.17.x rework of the app build/serving layer and no longer applies/builds against current dev, so this is a clean re-implementation rebased on dev, at parity with #31279.

Issue for this PR

Closes #19174
Closes #19119
Closes #27933
Addresses #27931
Addresses #30405
Addresses #19301

Note: #30405 is also addressed by the open PR #30399 — both add crossorigin="use-credentials" to the manifest link. Happy to drop that change if #30399 merges first.

Type of change

  • Bug fix
  • New feature

What does this PR do?

The web UI had no service worker, so every reload re-fetched all assets and the app couldn't be installed as a PWA.

Service worker — adds vite-plugin-pwa with registerType: 'prompt' and Workbox precaching for the static shell (JS, CSS, fonts, icons). Only explicit SPA routes (/, /new-session, /:dir, /:dir/session/:id?) receive the navigation fallback via a shared navigateFallbackAllowlist (extracted to src/pwa.ts); all other paths pass to the network. SW disabled in dev to preserve Vite HMR.

Update promptPwaUpdatePrompt shows a non-blocking banner when a new SW is waiting. Reload activates it; Dismiss defers it. Update logic lives in a pure pwa-update.ts controller (unit-tested without rendering). Mounted outside AppBaseProviders so it survives ErrorBoundary and connection errors.

Manifest fixes — adds id, scope, start_url, description, and screenshots; fixes theme_color from #ffffff to #F8F7F7; separate maskable and any icon entries per Chrome/Lighthouse guidance. Fields live in the canonical packages/ui/src/assets/favicon/site.webmanifest (shared via symlink) so app/web/console/enterprise stay DRY.

iOS — adds apple-mobile-web-app-capable, status bar style, and apple-touch-icon links for iPad (152×152, 167×167) alongside the existing 180×180.

Cache-ControlCache-Control: immutable on /assets/* in _headers, no-cache on root-level assets.

Proxy fixcrossorigin="use-credentials" on the manifest link (same fix as #30399).

How did you verify your code works?

  • bun test in packages/app passes (PWA allowlist, manifest field, and update-controller tests).
  • bun run build in packages/app — emits prompt-mode sw.js with the allowlist; manifest, icons, and _headers resolve; built index.html carries the crossorigin manifest link + apple-mobile meta tags.
  • Per-package bun typecheck clean.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

…navigation fallback)

Add Progressive Web App support to the browser app:

- vite-plugin-pwa with registerType "prompt" so stale service workers
  self-heal only when the user accepts the update prompt
- PwaUpdatePrompt: an idiomatic SolidJS JSX banner that surfaces a dismissible
  reload prompt when a new service worker is waiting; correctly unwraps the
  useRegisterSW Signal tuples. Its decision logic is extracted into a pure,
  zero-UI-import module (pwa-update.ts) and unit-tested directly, following the
  repo's established pattern (e.g. updater-action.ts) instead of rendering a
  component in bun test
- navigateFallbackAllowlist as a shared, test-asserted source of truth for the
  SPA routes that receive the offline app-shell fallback (/, /new-session,
  /:dir/session/:id?, bare /:dir with /doc excluded)
- enrich the shared canonical site.webmanifest (packages/ui) with installable
  PWA fields (id/start_url/scope, any+maskable icons, theme_color, screenshots)
  so packages/app keeps symlinking it — preserving the DRY favicon/manifest
  pipeline shared across app/web/console/enterprise

Co-authored-by: yui-soul <yui-soul@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

Potential Related PRs Found:

  1. fix(app): support authenticated web app manifests #30399fix(app): support authenticated web app manifests

  2. fix(server): add Cache-Control headers to static assets #27934fix(server): add Cache-Control headers to static assets

    • Related because the current PR also addresses cache-control headers with Cache-Control: immutable on /assets/* and no-cache on root-level assets.
  3. fix(app): add service worker for cache-first static asset loading #27936fix(app): add service worker for cache-first static asset loading

    • Related because both add service worker functionality, though the current PR appears to be a newer, more comprehensive reimplementation (it mentions being rebased on current dev after v1.17.x rework).

The PR supersedes #31279 (which is closed), so that's not a duplicate concern. The current PR is the clean re-implementation addressing multiple related issues (#19174, #19119, #27933, #27931, #30405, #19301).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant