mirror of
https://github.com/dergigi/boris.git
synced 2025-12-17 06:34:24 +01:00
- 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.
72 lines
2.1 KiB
TypeScript
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']
|
|
}
|
|
})
|
|
|