Files
boris/vite.config.ts
Gigi 418bcb0295 feat(pwa): upgrade to full PWA with vite-plugin-pwa
- Add web app manifest with proper metadata and icon support
- Configure vite-plugin-pwa with injectManifest strategy
- Migrate service worker to Workbox with precaching and runtime caching
- Add runtime caching for cross-origin images (preserves existing behavior)
- Add runtime caching for cross-origin article HTML for offline reading
- Create PWA install hook and UI component in settings
- Add online/offline status monitoring and toast notifications
- Add service worker update notifications
- Add placeholder PWA icons (192x192, 512x512, maskable variants)
- Update HTML with manifest link and theme-color meta tag
- Preserve existing relay/airplane mode functionality (WebSockets not intercepted)

The app now passes PWA installability criteria while maintaining all existing
offline functionality. Icons should be replaced with proper branded designs.
2025-10-11 20:41:49 +01:00

72 lines
2.1 KiB
TypeScript

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { VitePWA } from 'vite-plugin-pwa'
export default defineConfig({
plugins: [
react(),
VitePWA({
strategies: 'injectManifest',
srcDir: 'src',
filename: 'sw.ts',
injectRegister: null,
manifest: {
name: 'Boris - Nostr Bookmarks',
short_name: 'Boris',
description: 'Your reading list for the Nostr world. A minimal nostr client for bookmark management with highlights.',
start_url: '/',
scope: '/',
display: 'standalone',
theme_color: '#0f172a',
background_color: '#0b1220',
orientation: 'any',
categories: ['productivity', 'social', 'utilities'],
icons: [
{ src: '/icon-192.png', sizes: '192x192', type: 'image/png' },
{ src: '/icon-512.png', sizes: '512x512', type: 'image/png' },
{ src: '/icon-maskable-192.png', sizes: '192x192', type: 'image/png', purpose: 'maskable' },
{ src: '/icon-maskable-512.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' }
]
},
injectManifest: {
globPatterns: ['**/*.{js,css,html,ico,png,svg,webp}'],
globIgnores: ['**/_headers', '**/_redirects', '**/robots.txt']
},
devOptions: {
enabled: true,
type: 'module'
}
})
],
server: {
port: 9802
},
resolve: {
extensions: ['.js', '.ts', '.tsx', '.json'],
conditions: ['import', 'module', 'browser', 'default'],
preserveSymlinks: false,
mainFields: ['module', 'jsnext:main', 'jsnext', 'main']
},
optimizeDeps: {
include: ['applesauce-core', 'applesauce-factory', 'applesauce-relay', 'applesauce-react'],
esbuildOptions: {
resolveExtensions: ['.js', '.ts', '.tsx', '.json']
}
},
build: {
commonjsOptions: {
include: [/node_modules/],
transformMixedEsModules: true
},
rollupOptions: {
output: {
format: 'es'
}
}
},
ssr: {
noExternal: ['applesauce-core', 'applesauce-factory', 'applesauce-relay']
}
})