Progressive Web Apps in 2026 are more capable than ever, with install rates improving as browsers have made the install prompt more prominent. This guide covers the technical requirements for a PWA that actually gets installed, works offline, and sends push notifications.
PWA requirements in 2026
A PWA must meet these criteria to be installable in modern browsers:
- Served over HTTPS
- Has a registered Service Worker with a
fetchevent handler - Has a Web App Manifest with required fields
- Has at least one icon ≥ 192×192 pixels
- Has a
start_urlthat loads successfully
Web App Manifest
The manifest defines how the app appears when installed. Key fields:
{"name": "My App", "short_name": "App", "start_url": "/", "display": "standalone", "background_color": "#ffffff", "theme_color": "#000000", "icons": [{"src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png"}, {"src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable"}]}
- display: standalone — removes browser chrome. The installed app looks like a native app.
- purpose: maskable — the 512px icon should have safe zone padding to work with circular icon masks on Android.
Service Worker: cache strategies
The Service Worker is the key component that enables offline support. In Next.js, usenext-pwa or Workbox directly:
npm install next-pwa
Caching strategies:
| Strategy | Best for | Freshness |
|---|---|---|
| Cache First | Fonts, images, static assets | Stale until cache expires |
| Network First | API responses, user data | Always fresh when online |
| Stale While Revalidate | HTML pages, news feeds | Instant with background refresh |
Push notifications
Push notifications require:
- Request permission with
Notification.requestPermission() - Subscribe with
registration.pushManager.subscribe() - Send the subscription endpoint to your server
- Server sends notifications via the Web Push Protocol (using a library like
web-push) - Service Worker handles the
pushevent and displays the notification
VAPID keys are required for authentication between your server and the push service. Generate them with:
npx web-push generate-vapid-keys
Background sync
Background sync allows deferred actions to be retried when the user comes back online. Useful for form submissions, data sync, and upload queues:
navigator.serviceWorker.ready.then(reg => reg.sync.register('sync-forms'));
Install prompt UX
The browser fires a beforeinstallprompt event when the app meets install criteria. Capture it and show a custom install button:
let deferredPrompt; window.addEventListener('beforeinstallprompt', (e) => { e.preventDefault(); deferredPrompt = e; showInstallButton(); });
Don't show the install prompt on the first visit. Show it after the user has demonstrated engagement — 3+ page views, 2+ minutes on site, or after a meaningful action.
Lighthouse PWA audit
Lighthouse's PWA audit checks all installability requirements. Run it with:
lighthouse https://yoursite.com --only-categories=pwa
A score of 100 means the app is fully installable and follows PWA best practices.