rastrillo / pwa Public
--- name: rastrillo-pwa description: Add installation, a public offline fallback and service-worker update handling to a Rastrillo web app, with optional aviso Web Push composition. ---
Rastrillo PWA
Module and source: amadan.net/rastrillo/pwa. Read this skill from the version the app imports. This kit adds installability and an offline fallback, not offline data or writes. For the latter, read docs/offline.md before choosing an app data model.
Use examples/basic/main.go as the complete wiring reference. It is a separate Go module, so read it from the repository, not a module-cache zip.
- Create
pwa.Manifestwith stableID,Name,StartURL,Scopeand icons. Paths are root-relative, scope ends in/, and start URL stays within scope. Call.Handler()at boot and check the error. Supply actual 192x192 and 512x512 PNGs, plus a 180px Apple touch icon. Branding is app-owned. - Mount the manifest at
/manifest.webmanifest. Mountpwa.Assets()usinghttp.StripPrefix("/pwa", ...)at/pwa/. Assets have JavaScript MIME types andno-cache; add manifest, theme-colour and Apple icon head tags. - Serve app-owned
/sw.jsat its intended scope with JavaScript MIME andCache-Control: no-cache. It imports/pwa/worker.jsand callsRastrilloPWA.install()once. For/app/scope, use/app/sw.jsand matching manifest scope/start paths; asset helpers may live elsewhere. Serve the manifest and worker assets without authentication redirects. - Import
registerfrom/pwa/client.mjs. It returns a registration ornullwhen unsupported. It reports waiting updates throughonUpdate; it never reloads or asks for permission. Withoutclients.claim, the first page becomes controlled on its next navigation. Wait fornavigator.serviceWorker.readybefore passing the registration to push.
Update activation is app policy. Prefer asking people to save and close all tabs. activateUpdate(registration) explicitly activates a waiting worker and affects every tab in its scope. Call only after resolving unsaved work across them. The app owns any controllerchange reload.
The worker intercepts only in-scope GET navigations. Network failures get a 503 public offline page; 401/403/500 responses remain unchanged. API calls and writes stay on the network. No Cache Storage or IndexedDB writes. install({offlineHTML}) accepts a trusted, public, self-contained document for custom copy/translations. Its CSP permits inline style, no scripts or external assets. Never interpolate a signed-in person's data into it.
For push, load the pinned amadan.net/rastrillo/aviso skill and compose its worker handlers into the same /sw.js. Keep one registration per scope; do not register a second push worker over it. Aviso owns subscriptions and transport. The app owns notification policy, payloads and encryption. Push permission must be requested from a user gesture. On iOS, guide the person to install and sign in inside the Home Screen copy first.
Validate with make ci and the app's own gate. The module gate includes its nested example and Chromium/WebKit worker tests; physical-device install and push checks are separate. There is no native adapter in this module.