Key takeaways
- A Progressive Web App (PWA) is a website that can be installed on phones and desktops, open full-screen and work offline.
- It needs three things: HTTPS, a web app manifest and a service worker.
- PWAs are a cost-effective alternative to native apps for many businesses, content sites and internal tools.
Try it on this site: on Android Chrome, open the menu and choose “Install app” (or “Add to Home screen” on iPhone Safari). IFTIKHAR then opens like an app — with its own icon, a bottom tab bar and an offline page when there’s no connection. That’s a PWA, and you can build one for your business without app stores.
The three ingredients#
| Ingredient | Purpose |
|---|---|
| HTTPS | Required for service workers and installability |
| Web app manifest | Name, icons, colours, start URL and display mode |
| Service worker | A script that runs in the background, intercepts network requests and enables offline support and caching |
The manifest#
{
"name": "IFTIKHAR — SEO & Marketing Blog",
"short_name": "IFTIKHAR",
"start_url": "/?source=pwa",
"scope": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#7ed957",
"icons": [
{ "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" },
{ "src": "/icon-512-maskable.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
]
}
Link it in the head: <link rel="manifest" href="/manifest.webmanifest">.
A simple service worker#
// sw.js — network first for pages, cache fallback offline
const CACHE = 'site-v1';
self.addEventListener('install', e => self.skipWaiting());
self.addEventListener('activate', e => e.waitUntil(self.clients.claim()));
self.addEventListener('fetch', e => {
if (e.request.mode !== 'navigate') return;
e.respondWith(
fetch(e.request)
.then(res => { caches.open(CACHE).then(c => c.put(e.request, res.clone())); return res; })
.catch(() => caches.match(e.request).then(r => r || caches.match('/offline/')))
);
});
Register it from your page: navigator.serviceWorker.register('/sw.js'). The service worker must be served from the root (or a scope that covers the pages it controls).
Need a hand with this?
Get a quick, honest review of your website’s SEO.
Caching strategies#
| Strategy | Use for |
|---|---|
| Network first | HTML pages — fresh content, offline fallback |
| Cache first / stale-while-revalidate | CSS, JS, fonts, images with versioned URLs |
| Network only | Admin, checkout, APIs with private data |
/wp-admin/, previews and REST API calls with personal data. This theme’s service worker skips all of these and removes itself for logged-in editors.PWA vs native app#
| PWA | Native app | |
|---|---|---|
| Cost | One codebase (your website) | Separate iOS/Android development |
| Distribution | Any URL; installable from browser | App Store / Play Store review |
| SEO | Fully indexable | Not searchable on the web |
| Device features | Many (camera, location, push notifications incl. iOS 16.4+ for installed PWAs) | All |
| Best for | Content, e-commerce, booking, internal tools, dashboards | Heavy device integration, games, offline-first complex apps |
See web app vs mobile app vs PWA for a deeper decision guide.
Testing#
- Chrome DevTools → Application: check the manifest, service worker and cache storage.
- Toggle “Offline” in DevTools and reload to test the offline page.
- Bump the cache name on every release so old files are cleared.
PWA FAQ#
Do PWAs help SEO?#
Not directly, but they improve speed for repeat visits and engagement, and they remain fully crawlable websites.
Can a WordPress site be a PWA?#
Yes — through the theme (like this one) or a PWA plugin.
Can PWAs be listed in the Play Store?#
Yes, using a Trusted Web Activity wrapper (tools like Bubblewrap or PWABuilder).