Files
boris/PWA_IMPLEMENTATION.md

5.5 KiB

PWA Implementation Summary

Boris has been successfully upgraded to a full Progressive Web App (PWA)!

What Was Implemented

1. Web App Manifest

  • File: public/manifest.webmanifest
  • Includes app name, description, theme colors, and icon references
  • Configured for standalone display mode
  • Linked in index.html with theme-color meta tag

2. Service Worker with Workbox

  • File: src/sw.ts
  • Plugin: vite-plugin-pwa with injectManifest strategy
  • Features:
    • Precaching of app shell (HTML, CSS, JS assets)
    • Runtime caching for cross-origin images (30-day cache, max 300 entries)
    • Runtime caching for cross-origin article HTML (14-day cache, max 100 entries)
    • SPA navigation fallback for offline app loading
    • Automatic cleanup of old caches
    • WebSocket traffic is NOT intercepted - relay functionality preserved

3. PWA Install Experience

  • Hook: src/hooks/usePWAInstall.ts
  • Component: src/components/Settings/PWASettings.tsx
  • Captures beforeinstallprompt event
  • Shows install button in Settings when app is installable
  • Displays confirmation when app is already installed

4. Online/Offline Status

  • Hook: src/hooks/useOnlineStatus.ts
  • Monitors navigator.onLine status
  • Shows toast notification when going offline
  • Integrated into main App component

5. Service Worker Updates

  • Checks for updates hourly
  • Shows toast notification when new version is available
  • User can refresh to get latest version

Files Created/Modified

New Files

  • src/sw.ts - Workbox service worker
  • src/hooks/usePWAInstall.ts - Install prompt hook
  • src/hooks/useOnlineStatus.ts - Online status monitoring
  • src/components/Settings/PWASettings.tsx - Install UI
  • public/manifest.webmanifest - Web app manifest
  • public/icon-*.png - PWA icons (placeholders)

Modified Files

  • vite.config.ts - Added VitePWA plugin configuration
  • index.html - Added manifest link and theme-color
  • src/main.tsx - Enhanced SW registration
  • src/App.tsx - Added online/offline monitoring
  • src/components/Settings.tsx - Added PWA settings section
  • package.json - Added PWA dependencies

Icons

Branded icons now in place!

The following icons have been extracted from boris-favicon.zip and are ready:

  • public/icon-192.png - 192x192px PWA icon (from android-chrome-192x192.png)
  • public/icon-512.png - 512x512px PWA icon (from android-chrome-512x512.png)
  • public/icon-maskable-192.png - 192x192px maskable variant
  • public/icon-maskable-512.png - 512x512px maskable variant
  • public/favicon.ico - Standard favicon
  • public/favicon-16x16.png - 16x16 favicon
  • public/favicon-32x32.png - 32x32 favicon
  • public/apple-touch-icon.png - iOS home screen icon

Note: The maskable icons currently use the same images as standard icons. If you want optimal maskable appearance with safe area padding, consider creating dedicated maskable variants with ~20% padding on all sides.

Testing PWA Functionality

Local Development

npm run build
npm run preview  # or serve the dist/ folder

What to Test

  1. Install prompt: Visit in Chrome/Edge, check for install button in Settings
  2. Offline mode: Disconnect network, verify app shell loads
  3. Cached images: View articles with images, go offline, images still load
  4. Cached articles: View external articles, go offline, articles still available
  5. Relay connectivity: Verify local relay and WebSocket connections work
  6. Updates: Deploy new version, verify update notification appears

Lighthouse PWA Audit

Run in Chrome DevTools:

  1. Open DevTools (F12)
  2. Go to Lighthouse tab
  3. Select "Progressive Web App" category
  4. Run audit

Expected scores:

  • Installable
  • PWA Optimized
  • Works offline
  • ⚠️ Icons (will pass after replacing placeholders)

Build Output

The build process now:

  1. Compiles TypeScript and bundles assets
  2. Generates Workbox service worker from src/sw.ts
  3. Injects precache manifest with all app assets
  4. Outputs dist/sw.js and dist/manifest.webmanifest

Build command:

npm run build

Deployment Notes

Vercel/Cloudflare/Netlify

  • No special configuration needed
  • _headers, _redirects, _routes.json already excluded from precache
  • Service worker will be served at /sw.js
  • Manifest will be served at /manifest.webmanifest

CDN Considerations

  • Set proper cache headers for sw.js (short cache, must-revalidate)
  • App assets can have long cache (they're versioned)
  • Icons and manifest can have moderate cache (1 hour - 1 day)

Existing Functionality Preserved

Local Relay: WebSocket connections not intercepted by SW Airplane Mode: Existing offline sync functionality intact Image Caching: Behavior preserved, now using Workbox Nostr Events: All relay operations work as before

Next Steps

  1. Replace icon placeholders with branded designs
  2. Test install flow on mobile devices (iOS Safari, Android Chrome)
  3. Test offline experience thoroughly
  4. Monitor service worker updates in production
  5. Consider adding:
    • Web Share Target (share to Boris from system share sheet)
    • Background Sync (queue writes when offline)
    • Badging API (unread counts on app icon)
    • Push notifications (optional, requires push service)

Resources