feat(web): make TaskForge an installable PWA#3
Merged
Conversation
Adds a web app manifest, generated icon set, and a service worker so the app can be installed to the home screen / desktop. - Manifest lives in src/pwa/manifest.ts so tsc and vitest see it; its test guards Chrome's installability rules and that each icon src exists on disk, since a stale icon path breaks install silently. - Icons rasterize from assets/pwa/*.svg via puppeteer (already a devDep). Separate maskable art: full-bleed, glyph inside the 80% safe zone. iOS apple-touch-icon renders from it too, as iOS composites alpha on black. - Service worker precaches the app shell only. No runtimeCaching for /api: routes are session-gated and boards are shared, so cached responses would outlive logout in Cache Storage. /api and /ws are denylisted from the navigation fallback. Verified against the built app: SW activates, manifest parses, all icons resolve, and /api returns JSON rather than the HTML shell — through both vite preview and the NestJS static-asset path used in production. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Makes the web app installable — "Install app" on desktop/Android, "Add to Home Screen" on iOS. Adds a web app manifest, a generated icon set, and a service worker via
vite-plugin-pwa.Why these choices
Manifest lives in
src/pwa/manifest.ts, not beside the vite config, sotscand vitest both see it.manifest.test.tsasserts Chrome's installability rules and that every iconsrcresolves to a real file — renaming the art without regenerating icons breaks install silently: the app still builds and loads, it just stops offering "Install".Icons are generated, not committed by hand. Source art is
assets/pwa/*.svg;pnpm --filter @taskforge/web iconsrasterizes topublic/icons/*.pngusing puppeteer, already a devDep forscripts/screenshots.mjs. PNG rather than SVG because iOS home-screen icons and Android launcher tiles need raster. The maskable icon is separate and full-bleed — the launcher crops to its own shape and supplies the rounding, so reusing the rounded-corner art would round already-rounded corners.apple-touch-iconrenders from the maskable art because iOS composites alpha against black.The service worker precaches the app shell only — no
runtimeCachingfor/api. Every route is session-gated and boards are shared between users, so caching API responses would park another user's task data in Cache Storage, where logout doesn't reach it./apiand/wsare denylisted from the navigation fallback; without that the SW answers XHRs and the socket handshake with the HTML shell.Verification
Driven against the built app, through both
vite previewand the NestJSuseStaticAssetspath used in production:/manifest.webmanifest→ 200application/manifest+json, parses (not swallowed by the SPA fallback)image/pngGET /api/auth/statusreturns JSON, not the HTML shellsw.jsservedmax-age=0, so updates propagatevitest run: 133 passed (14 files).tsc --noEmit: 3 errors, the same 3 pre-existing ones AGENTS.md documents — count unchanged.Notes
vite devemits no manifest or SW, so install isn't offered on :5173.🤖 Generated with Claude Code