Files
boris/PWA_IMPLEMENTATION.md

5.2 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

Icon Placeholders

⚠️ IMPORTANT: Replace placeholder icons with proper branded designs!

Current placeholders are minimal 1x1 pixel images. You need:

  • public/icon-192.png - 192x192px app icon
  • public/icon-512.png - 512x512px app icon
  • public/icon-maskable-192.png - 192x192px with safe area padding
  • public/icon-maskable-512.png - 512x512px with safe area padding

Maskable icons should have ~20% padding on all sides to ensure they look good on all devices.

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