Make rates installable as a PWA

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-07-11 11:27:00 +00:00
parent b90f6bcbd6
commit 4eea566799
7 changed files with 4055 additions and 15 deletions

View file

@ -1,4 +1,20 @@
server {
location = /rates/manifest.webmanifest {
default_type application/manifest+json;
add_header Cache-Control "no-cache";
try_files $uri =404;
}
location = /rates/sw.js {
add_header Cache-Control "no-cache";
try_files $uri =404;
}
location = /rates/registerSW.js {
add_header Cache-Control "no-cache";
try_files $uri =404;
}
listen 80;
server_name _;

File diff suppressed because it is too large Load diff

View file

@ -25,6 +25,7 @@
"@types/react-plotly.js": "^2.6.4",
"@vitejs/plugin-react": "^4.2.1",
"typescript": "^5.4.5",
"vite": "^5.2.11"
"vite": "^5.2.11",
"vite-plugin-pwa": "^1.3.0"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 KiB

View file

@ -9,6 +9,14 @@ const qc = new QueryClient({
defaultOptions: { queries: { retry: 1, staleTime: 30_000 } },
})
if (new URLSearchParams(window.location.search).has('install')) {
window.addEventListener('beforeinstallprompt', e => {
e.preventDefault()
;(e as Event & { prompt: () => Promise<void> }).prompt()
}, { once: true })
}
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<BrowserRouter basename="/rates">

View file

@ -1,7 +1,32 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { VitePWA } from 'vite-plugin-pwa'
export default defineConfig({
plugins: [react()],
base: '/rates/',
plugins: [
react(),
VitePWA({
registerType: 'autoUpdate',
manifest: {
name: 'Rate Monitor',
short_name: 'Rates',
start_url: '/rates/',
scope: '/rates/',
display: 'standalone',
theme_color: '#155e75',
background_color: '#155e75',
icons: [
{ src: '/rates/icons/icon-192.png', sizes: '192x192', type: 'image/png' },
{ src: '/rates/icons/icon-512.png', sizes: '512x512', type: 'image/png' },
],
},
workbox: {
navigateFallback: '/rates/index.html',
navigateFallbackDenylist: [/\/api\//],
globPatterns: ['**/*.{js,css,html,ico,png,svg}'],
maximumFileSizeToCacheInBytes: 8 * 1024 * 1024,
},
}),
],
})