Repository navigation
[6/10] Make Catalyse installable as a PWA - #358
Merged
Merged
Conversation
hturnbull93
force-pushed
the
threaded-replies
branch
from
October 21, 2026 13:15
9101906 to
ad3162c
Compare
hturnbull93
force-pushed
the
threaded-replies
branch
from
October 22, 2026 17:17
ad3162c to
016e1f5
Compare
hturnbull93
force-pushed
the
threaded-replies
branch
from
October 22, 2026 17:36
016e1f5 to
025b56b
Compare
hturnbull93
force-pushed
the
threaded-replies
branch
2 times, most recently
from
October 23, 2026 09:16
24beed6 to
337bd4b
Compare
hturnbull93
force-pushed
the
threaded-replies
branch
from
October 23, 2026 09:17
337bd4b to
1521bfe
Compare
hturnbull93
force-pushed
the
threaded-replies
branch
from
October 23, 2026 15:09
1521bfe to
e4fc1e5
Compare
hturnbull93
force-pushed
the
pwa
branch
4 times, most recently
from
October 23, 2026 23:10
15c267d to
088eefc
Compare
A web app manifest with home-screen icons rendered from app/icon.svg (the round logo at 192px and 512px, a full-bleed square for the maskable and Apple icons), and theme colours for light and dark. A service worker, registered in production builds only, sends navigations network-first and falls back to a cached offline.html only when the network fails; nothing else is intercepted or cached. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
🚅 Deployed to the catalyse-pr-358 environment in PauseAI Catalyse
|
UpdatePrompt checks version.get when the app comes back into view and every ten minutes, and shows "A new version of Catalyse is available" with Refresh and Later when the server's commit differs from the page's. The page knows its own deploy from Next's deploymentId, set to RAILWAY_GIT_COMMIT_SHA (now passed into the Docker build); without one, as in a local build, it takes the first version the server reports. Later hides the prompt until a newer deploy still. deploymentId also makes Next reload, rather than client-navigate, a page that navigates into a newer deploy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch had an error being deployed
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.
Screenshots: https://fedora.taila91c66.ts.net:8444/docs/20261021-134259-pr-358-installable-app-and-offline-page.html
Makes Catalyse installable on a phone's home screen, with an offline page when there is no connection, and offers a refresh when a newer version has been deployed. No data or API changes.
Manifest and icons
app/manifest.ts(served at/manifest.webmanifest, linked automatically by Next): name,short_name"Catalyse",display: standalone,start_url: /dashboard,scope: /, 192/512 icons and a 512 maskable icon.app/apple-icon.png(180px) gives iOS itsapple-touch-icon;appleWebAppmetadata sets the home-screen title.viewport.themeColorsets a light (#ffffff) and dark (#1f2937)theme-color, matching the header's surface colour.app/icon.svgwith Playwright's Chromium: the round logo for the 192/512 "any" icons, and a full-bleed orange square with white pause bars (inside the maskable safe zone) for the maskable and Apple icons.Service worker
public/sw.jsintercepts navigations only, network-first. It falls back to a cached/offline.htmlonly when the network request fails, so it never serves stale app code after a deploy. API calls, JS/CSS chunks and signed-in pages are never intercepted or cached; the only cached entry is the offline page. Old caches are deleted on activate.components/ServiceWorker.tsxregisters it withupdateViaCache: 'none', in production builds only./sw.jsis also servedCache-Control: no-cache.public/offline.htmlis a self-contained page (inline styles and logo) that follows the app's light/dark choice and has a "Try again" link that reloads the page it replaced.New version prompt
next.config.tssetsdeploymentIdtoRAILWAY_GIT_COMMIT_SHA, which theDockerfilenow passes into the build. Next writes it on<html>asdata-dpl-id, adds?dpl=to asset URLs, and reloads (rather than client-navigates) a page that navigates into a newer deploy.components/UpdatePrompt.tsxchecks the existingversion.getwhen the app comes back into view and every ten minutes. When the server's commit differs from the page's, it shows "A new version of Catalyse is available." with Refresh (reloads) and Later (hides it until a newer deploy still). It never reloads on its own, so nothing half-typed is lost.devreports'dev'), the page takes the first version the server reports as its own.Sign-in
localStorageper origin. A standalone app on the same origin shares that storage on Android. The e2e test signs in, goes offline, comes back and reaches the volunteer-only Projects page still signed in.Tests
components/UpdatePrompt.test.tsx: hidden when versions match; shown when the page is older; first-seen fallback without a deployment id; Later holds until a newer deploy. The defaultreloadcan only be clicked, not observed: jsdom'slocation.reloadis a silent no-op and can't be spied, so the asserting test passes its ownreload.app/misc.test.tsx); registration in production, none outside it, none withoutnavigator.serviceWorker, and a warning when registration fails (components/ServiceWorker.test.tsx).52-installable-app.spec.ts: the home page links the manifest, apple-touch-icon and both theme colours, and every manifest icon is served as PNG. With the worker in control, going offline shows the offline page (snapped), reconnecting and pressing Try again brings back Projects, and Cache Storage then holds only/offline.html. Passed 8 runs in a row on its own.Decisions
start_urlis/dashboard: a signed-in volunteer lands on their home, and a signed-out one is sent to/loginas usual.theme_color, so it uses the light value. Dark mode comes from the<meta name="theme-color" media=…>pair. That pair follows the OS setting, not the in-app theme toggle.public/, not Serwist or next-pwa: it is about 30 lines and adds no dependency.CACHEmust be renamed whenoffline.htmlchanges so installed copies pick up the new page (a comment insw.jssays this).app/icon.svg, andpublic/icons/holds its output.Manual checks on real phones (not possible here)
/dashboardwith the right icon (maskable, not letterboxed) and status-bar colour in light and dark.RAILWAY_GIT_COMMIT_SHAat build time (the page's<html>should carrydata-dpl-id). Without it the prompt falls back to the first version seen, which still works but misses a deploy that lands between the page loading and its first check.Closes #348
🤖 Generated with Claude Code