PWA: Make Your Site Work Offline and Install on Mobile
Your site works when the network is gone and installs to the home screen like an app — with no store and no developer account.
Most people assume "app" means a store, a company, and a developer account. In reality, almost everything a user needs from an app already exists on the web: it opens fast, works while disconnected, and has an icon on the home screen.
The technical name is PWA. It is not a framework or a library — it is three things you add to a site you already have.
One: the manifest file
A small JSON file that tells the browser the app name, icons, bar colour, and how to open. Without it, the browser will not consider the site installable.
- Icons: at least 192 and 512 px, including a maskable variant so Android does not crop it badly.
- display: standalone — opens without the browser chrome.
- start_url — the page it opens on.
Two: the Service Worker
This is the file that runs in the background and intercepts network requests. Without it the site is just a page; with it, the site can cache files and serve them when the network dies.
- install — decide which core files to cache the first time (shell, icons, fonts).
- activate — clean out the old cache.
- fetch — decide per request: network or cache?
The most dangerous mistake: caching everything and forgetting to update it. The user then sees an old copy of your site and has no idea why.
Three: the right caching strategy
There is no single correct strategy for everything. This combination works:
- Shell (HTML): network first, cache as fallback — so users see the new version.
- Static assets (images, audio, fonts): cache first. They do not change daily.
- Volatile data: do not cache, or cache with a very short lifetime.
The update problem — and it hurts
When you deploy a new version, the old Service Worker stays in control until open pages are closed. The result: the user does not see your update and may report that "the site broke".
- Put a version number inside the Service Worker file, and change it on every deploy.
- When a new version is detected, show the user an "update" button instead of forcing it.
- On click, send
SKIP_WAITINGand reload.
This is exactly what I did on my Noor Al-Sighar app: every deploy carries a new build number, and the user takes the update when they choose — not abruptly mid-session.
Three mistakes that stop the install prompt
- No HTTPS: mandatory.
localhostis the only exception. - Manifest not linked: you need
<link rel="manifest">in the head. - No Service Worker registered: you need a registration line in JavaScript, or the browser will not treat it as an app.
Is it worth it?
If your site is visited from mobile more than once — yes. The difference in first-load speed on a return visit is significant, especially on weak connections. And if the site has audio or video content, the value multiplies because you are not re-downloading it every time.
Start with these three things only, and measure the difference before adding complexity.