feat(pwa): add Progressive Web App support — installable to homescreen
- vite-plugin-pwa with generateSW strategy (Workbox) - manifest.webmanifest: name, short_name, display standalone, theme_color #e8a820 - Service worker: precaches JS/CSS/HTML shell; API routes network-first (60s); Google Fonts cache-first (1 year) - Icons: 192 + 512px regular + maskable variants generated from App.vue bird SVG - index.html: theme-color meta, apple-touch-icon, apple-mobile-web-app-* tags for iOS Safari homescreen support (iOS ignores the manifest icons array) - autoUpdate mode: new versions install silently and activate on next navigation
This commit is contained in:
parent
e2c358c90a
commit
7e0722cc23
8 changed files with 4756 additions and 10 deletions
|
|
@ -2,8 +2,13 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="/icons/icon-192.png" />
|
||||
<link rel="apple-touch-icon" href="/icons/icon-192.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
||||
<meta name="theme-color" content="#e8a820" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
<meta name="apple-mobile-web-app-title" content="Kiwi" />
|
||||
<title>Kiwi — Pantry Tracker</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
|
|
|
|||
4686
frontend/package-lock.json
generated
4686
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -20,6 +20,7 @@
|
|||
"@vue/tsconfig": "^0.8.1",
|
||||
"typescript": "~5.9.3",
|
||||
"vite": "^7.1.7",
|
||||
"vite-plugin-pwa": "^1.2.0",
|
||||
"vue-tsc": "^3.1.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
BIN
frontend/public/icons/icon-192.png
Normal file
BIN
frontend/public/icons/icon-192.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
BIN
frontend/public/icons/icon-512.png
Normal file
BIN
frontend/public/icons/icon-512.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.3 KiB |
BIN
frontend/public/icons/maskable-192.png
Normal file
BIN
frontend/public/icons/maskable-192.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
frontend/public/icons/maskable-512.png
Normal file
BIN
frontend/public/icons/maskable-512.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
|
|
@ -1,9 +1,79 @@
|
|||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import { VitePWA } from 'vite-plugin-pwa'
|
||||
import { fileURLToPath, URL } from 'node:url'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
plugins: [
|
||||
vue(),
|
||||
VitePWA({
|
||||
registerType: 'autoUpdate',
|
||||
// generateSW strategy: Workbox builds the service worker at build time.
|
||||
// autoUpdate means new versions install in the background and activate
|
||||
// on next navigation — no "click to reload" prompt needed.
|
||||
strategies: 'generateSW',
|
||||
includeAssets: ['icons/icon-192.png', 'icons/icon-512.png', 'icons/maskable-192.png', 'icons/maskable-512.png'],
|
||||
manifest: {
|
||||
name: 'Kiwi — Pantry Tracker',
|
||||
short_name: 'Kiwi',
|
||||
description: 'Track your pantry, cut food waste, get recipe ideas from what you have.',
|
||||
theme_color: '#e8a820',
|
||||
background_color: '#1e1c1a',
|
||||
display: 'standalone',
|
||||
orientation: 'portrait',
|
||||
scope: '/',
|
||||
start_url: '/',
|
||||
icons: [
|
||||
{
|
||||
src: '/icons/icon-192.png',
|
||||
sizes: '192x192',
|
||||
type: 'image/png',
|
||||
},
|
||||
{
|
||||
src: '/icons/icon-512.png',
|
||||
sizes: '512x512',
|
||||
type: 'image/png',
|
||||
},
|
||||
{
|
||||
src: '/icons/maskable-192.png',
|
||||
sizes: '192x192',
|
||||
type: 'image/png',
|
||||
purpose: 'maskable',
|
||||
},
|
||||
{
|
||||
src: '/icons/maskable-512.png',
|
||||
sizes: '512x512',
|
||||
type: 'image/png',
|
||||
purpose: 'maskable',
|
||||
},
|
||||
],
|
||||
},
|
||||
workbox: {
|
||||
// Precache the built JS/CSS/HTML shell. API calls are always network-first.
|
||||
globPatterns: ['**/*.{js,css,html,ico,png,svg,woff2}'],
|
||||
runtimeCaching: [
|
||||
{
|
||||
// API: network-first, fall back to cache for 1 minute
|
||||
urlPattern: /^\/api\//,
|
||||
handler: 'NetworkFirst',
|
||||
options: {
|
||||
cacheName: 'kiwi-api-cache',
|
||||
expiration: { maxEntries: 50, maxAgeSeconds: 60 },
|
||||
},
|
||||
},
|
||||
{
|
||||
// Google Fonts: cache-first (fonts rarely change)
|
||||
urlPattern: /^https:\/\/fonts\.(googleapis|gstatic)\.com\//,
|
||||
handler: 'CacheFirst',
|
||||
options: {
|
||||
cacheName: 'google-fonts',
|
||||
expiration: { maxEntries: 10, maxAgeSeconds: 60 * 60 * 24 * 365 },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
base: process.env.VITE_BASE_URL ?? '/',
|
||||
resolve: {
|
||||
alias: {
|
||||
|
|
|
|||
Loading…
Reference in a new issue