Skip to content

Commit 7c935b3

Browse files
schwanndenclaude
andauthored
feat(pwa): rebuild offline support with Workbox and modernize install UX (#88)
The hand-written public/sw.js precached CRA-era paths (/static/js/bundle.js, /static/css/main.css) that 404 in the Vite build, so cache.addAll rejected and the service worker never finished installing — offline was broken entirely. Replace it with vite-plugin-pwa (injectManifest): Workbox injects the real hashed-asset precache manifest, and a custom src/sw.ts adds a NetworkFirst navigation handler with an app-shell offline fallback, StaleWhileRevalidate for Supabase REST reads (now covering family prayers too), and a bounded CacheFirst for storage images. Navigations stay network-first so online visitors and crawlers always get the freshly prerendered HTML — the Pages deploy/prerender pipeline is unchanged (SW is bypassed during snapshotting). Make the installed app more useful and cross-platform: - maskable icons (192/512) with Android safe-zone padding - apple-touch-icon (180), Apple meta tags, and iOS splash screens - wired favicons and light/dark theme-color - manifest id/scope/lang/categories, app shortcuts, and install screenshots - in-app "update available" toast and an Install button (beforeinstallprompt) Assets are generated by scripts/generate-pwa-assets.mjs (reuses the existing puppeteer + cached Chromium; not part of CI). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 93ef484 commit 7c935b3

31 files changed

Lines changed: 9262 additions & 4318 deletions

index.html

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,95 @@
2121
<meta name="twitter:card" content="summary_large_image" />
2222
<meta name="twitter:site" content="@sim_taiwan" />
2323

24-
<!-- PWA Manifest -->
25-
<link rel="manifest" href="/manifest.json" />
26-
<meta name="theme-color" content="#ffffff" />
24+
<!-- Favicons (the manifest <link> is injected by vite-plugin-pwa) -->
25+
<link rel="icon" href="/favicon.ico" sizes="any" />
26+
<link
27+
rel="icon"
28+
type="image/png"
29+
sizes="32x32"
30+
href="/icons/icon-32x32.png"
31+
/>
32+
<link
33+
rel="icon"
34+
type="image/png"
35+
sizes="16x16"
36+
href="/icons/icon-16x16.png"
37+
/>
38+
39+
<!-- iOS / standalone home-screen support -->
40+
<link rel="apple-touch-icon" href="/icons/apple-touch-icon.png" />
41+
<meta name="apple-mobile-web-app-capable" content="yes" />
42+
<meta name="mobile-web-app-capable" content="yes" />
43+
<meta
44+
name="apple-mobile-web-app-status-bar-style"
45+
content="black-translucent"
46+
/>
47+
<meta name="apple-mobile-web-app-title" content="SIM Prayers" />
48+
49+
<!-- iOS standalone launch (splash) screens — generated by
50+
scripts/generate-pwa-assets.mjs -->
51+
<link
52+
rel="apple-touch-startup-image"
53+
media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
54+
href="/icons/splash/apple-splash-430-932-3x.png"
55+
/>
56+
<link
57+
rel="apple-touch-startup-image"
58+
media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
59+
href="/icons/splash/apple-splash-393-852-3x.png"
60+
/>
61+
<link
62+
rel="apple-touch-startup-image"
63+
media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
64+
href="/icons/splash/apple-splash-390-844-3x.png"
65+
/>
66+
<link
67+
rel="apple-touch-startup-image"
68+
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
69+
href="/icons/splash/apple-splash-414-896-3x.png"
70+
/>
71+
<link
72+
rel="apple-touch-startup-image"
73+
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
74+
href="/icons/splash/apple-splash-414-896-2x.png"
75+
/>
76+
<link
77+
rel="apple-touch-startup-image"
78+
media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
79+
href="/icons/splash/apple-splash-375-667-2x.png"
80+
/>
81+
<link
82+
rel="apple-touch-startup-image"
83+
media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
84+
href="/icons/splash/apple-splash-1024-1366-2x.png"
85+
/>
86+
<link
87+
rel="apple-touch-startup-image"
88+
media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
89+
href="/icons/splash/apple-splash-834-1194-2x.png"
90+
/>
91+
<link
92+
rel="apple-touch-startup-image"
93+
media="(device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
94+
href="/icons/splash/apple-splash-820-1180-2x.png"
95+
/>
96+
<link
97+
rel="apple-touch-startup-image"
98+
media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
99+
href="/icons/splash/apple-splash-768-1024-2x.png"
100+
/>
101+
102+
<!-- Theme color follows light/dark to match the app background -->
103+
<meta
104+
name="theme-color"
105+
media="(prefers-color-scheme: light)"
106+
content="#f8fafc"
107+
/>
108+
<meta
109+
name="theme-color"
110+
media="(prefers-color-scheme: dark)"
111+
content="#020817"
112+
/>
27113
</head>
28114

29115
<body>

0 commit comments

Comments
 (0)