Convert Any Website into an Installable App with PWA (Full Guide + Complete Working Files)
Turn your website into a fast, installable app using Progressive Web App (PWA). This complete tutorial includes manifest.json, service-worker.js, offline.html, install button, and production-ready caching strategies.
✅ BLOG POST (FULL)
Why PWA?
A Progressive Web App (PWA) makes your website behave like a real mobile app. Users can:
Install it on Android/desktop
Open it in full-screen mode
Use it even when internet is off (offline mode)
Enjoy faster loading via smart caching
PWA requirements:
✅ HTTPS
✅ manifest.json
✅ service-worker.js
1) Folder Structure (Recommended)
Create these files in your site root:
/manifest.json
/service-worker.js
/offline.html
/assets/icons/icon-72.png
/assets/icons/icon-96.png
/assets/icons/icon-128.png
/assets/icons/icon-144.png
/assets/icons/icon-192.png
/assets/icons/icon-512.png
Icons should be exact sizes (important for installation).
2) FILE: manifest.json (COMPLETE)
Create: /manifest.json
{
"name": "Faulink Systems",
"short_name": "Faulink",
"description": "Smart digital solutions for schools, businesses & organizations.",
"start_url": "/index.php",
"scope": "/",
"display": "standalone",
"orientation": "portrait",
"background_color": "#0b1220",
"theme_color": "#0066cc",
"icons": [
{ "src": "/assets/icons/icon-72.png", "sizes": "72x72", "type": "image/png" },
{ "src": "/assets/icons/icon-96.png", "sizes": "96x96", "type": "image/png" },
{ "src": "/assets/icons/icon-128.png", "sizes": "128x128","type": "image/png" },
{ "src": "/assets/icons/icon-144.png", "sizes": "144x144","type": "image/png" },
{ "src": "/assets/icons/icon-192.png", "sizes": "192x192","type": "image/png" },
{ "src": "/assets/icons/icon-512.png", "sizes": "512x512","type": "image/png" }
]
}
3) FILE: offline.html (COMPLETE)
Create: /offline.html
4) FILE: service-worker.js (PRODUCTION READY)
Create: /service-worker.js
✅ Strategy:
Pages (navigation): network-first, fallback cache index/offline
Assets: cache-first, save runtime assets
Safe caching (missing file haivunji install)
const CACHE_NAME = "faulink-v1";
const CORE_ASSETS = [
"/",
"/index.php",
"/offline.html",
"/manifest.json",
"/assets/icons/icon-72.png",
"/assets/icons/icon-96.png",
"/assets/icons/icon-128.png",
"/assets/icons/icon-144.png",
"/assets/icons/icon-192.png",
"/assets/icons/icon-512.png"
];
// Install
self.addEventListener("install", (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then(async (cache) => {
await Promise.all(
CORE_ASSETS.map((url) => cache.add(url).catch(() => null))
);
})
);
self.skipWaiting();
});
// Activate (cleanup old caches)
self.addEventListener("activate", (event) => {
event.waitUntil(
caches.keys().then((keys) =>
Promise.all(keys.map((k) => (k !== CACHE_NAME ? caches.delete(k) : null)))
)
);
self.clients.claim();
});
// Fetch
self.addEventListener("fetch", (event) => {
const req = event.request;
// 1) Handle page navigation (HTML)
if (req.mode === "navigate") {
event.respondWith(
fetch(req)
.then((res) => {
const copy = res.clone();
caches.open(CACHE_NAME).then((cache) => cache.put(req, copy));
return res;
})
.catch(async () => {
const cache = await caches.open(CACHE_NAME);
return (
(await cache.match(req)) ||
(await cache.match("/index.php")) ||
(await cache.match("/offline.html"))
);
})
);
return;
}
// 2) Handle assets (CSS/JS/IMG)
event.respondWith(
caches.match(req).then((cached) => {
if (cached) return cached;
return fetch(req)
.then((res) => {
// Save runtime assets for offline use
const copy = res.clone();
caches.open(CACHE_NAME).then((cache) => cache.put(req, copy));
return res;
})
.catch(async () => {
// If offline & no cache, just return nothing (browser handles)
return cached;
});
})
);
});
5) Add PWA tags inside
(COMPLETE) Add these in your index.php
: 6) Register the Service Worker (COMPLETE) Before : 7) Install Button (NEVER DISAPPEARS) Add a button anywhere (Navbar/Hero). Example: Then add this script: 8) Testing Checklist (Important) ✅ Open your site in Chrome ✅ DevTools → Application tab Manifest: should load correctly Service Worker: active ✅ Turn off internet → refresh → should show cached index/offline page If changes don’t apply: Change cache version faulink-v1 → faulink-v2 DevTools → Application → Service Workers → Unregister → Reload BONUS: Pro Tips Cache only important pages (index, login pages, icons) Don’t aggressively cache dynamic pages that require live DB Keep “offline.html” lightweight and helpful Use 192 + 512 icons always (mandatory for install on Android) ✅ Ready-to-Publish Conclusion (Premium) With only three files (manifest.json, service-worker.js, and offline.html), you can turn your website into a professional installable app that works offline and feels like a native application.
🚀 Unahitaji mfumo au website ya biashara?
Chagua huduma hapa chini kisha mteja bofya moja kwa moja kwenda kwenye ukurasa wa huduma au kuwasiliana nasi kwa WhatsApp.