How to turn a website into a PWA in 2026
A step-by-step, 2026-accurate guide to making any website installable — manifest, service worker, iOS Safari, install prompt, and analytics.
Turning a website into a Progressive Web App used to take a week. In 2026 it takes about an hour once you know the checklist. This guide walks through every step, with the iOS quirks that most tutorials still get wrong.
What counts as a PWA in 2026
A PWA is any website that meets three baseline requirements: it is served over HTTPS, it ships a manifest.webmanifest file that describes the app, and it registers a service worker for offline behaviour. Once those three things are in place, every mainstream browser will offer to install your site.
Step 1 — Add a Web App Manifest
Create public/manifest.webmanifest:
{
"name": "Your product",
"short_name": "Product",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#111827",
"icons": [
{ "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" }
]
}
Link it from your <head>: <link rel="manifest" href="/manifest.webmanifest">. Ship the two icons at exactly the sizes listed.
Step 2 — Register a service worker
Add a minimal public/sw.js that caches the shell:
self.addEventListener('install', (e) => e.waitUntil(caches.open('v1').then((c) => c.addAll(['/']))));
self.addEventListener('fetch', (e) => e.respondWith(caches.match(e.request).then((r) => r || fetch(e.request))));
Register it once from your app entry: navigator.serviceWorker.register('/sw.js').
Step 3 — Handle iOS Safari
Safari on iOS 16.4+ supports installation and web push, but it will never fire the beforeinstallprompt event. You have to render your own instructions: "Tap the Share button, then Add to Home Screen." Detect iOS with /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream and show the guide only when the user is on Safari and not already installed.
Step 4 — Show an install popup
The browser's default install prompt lives behind a small icon in the address bar. Most visitors never notice it. The single biggest lift on install rate is an in-page popup with your branding, triggered at the right moment (after 2 pageviews, after 30 seconds, or on a specific route). This is exactly what InstantPWA does — a customizable popup you drop in with one script tag.
Step 5 — Measure it
Instrument four events: impression (popup shown), click (user tapped install), installed (fired by appinstalled), and dismissed. The ratio of install to impression is your PWA conversion rate — aim for 3–8% on cold traffic, 15%+ on returning visitors.
Common mistakes
- Serving the manifest from a subdomain — it must be same-origin.
- Forgetting
"purpose": "any maskable"on the 512×512 icon — Android will refuse to install. - Firing your install popup on the first pageview — bounces spike, installs don't.
Where to go next
Read our case studies for the 14 documented PWA wins from Pinterest, Twitter Lite, Starbucks, Tinder and more, or try InstantPWA free and skip the plumbing entirely.
Ship your install prompt in 60 seconds
InstantPWA is one line of code. Free forever for one widget, no card required.
Get started free