I have a PWA that works on a desktop browser and shows the install icon in the address bar (Brave and Chrome browsers). There is a manifest.json and the service worker (sw.js) is recognised, and DevTools show it as running. So I am reasonably sure my code is complete.
This is my sw.js file:
// Service Worker
const cacheName = "paul-address";
const filesToCache = [
"/test/",
"/test/index.html",
"/test/js/index.js",
"/test/styles/styles.css"
];
self.addEventListener("install", e => {
console.log("[ServiceWorker**] Install");
e.waitUntil(
caches.open(cacheName).then(cache => {
console.log("[ServiceWorker**] Caching app shell");
return cache.addAll(filesToCache);
})
);
});
self.addEventListener("activate", event => {
caches.keys().then(keyList => {
return Promise.all(
keyList.map(key => {
if (key !== cacheName) {
console.log("[ServiceWorker] - Removing old cache", key);
return caches.delete(key);
}
})
);
});
});
// sw.js - Cache-first strategy for static assets
self.addEventListener('fetch', event => {
// Only handle GET requests
if (event.request.method !== 'GET') return;
const url = new URL(event.request.url);
// Cache-first for static assets
if (url.pathname.match(/\.(css|js|png|jpg|jpeg|gif|svg|ico)$/)) {
event.respondWith(
caches.match(event.request)
.then(response => {
if (response) {
console.log('Serving from cache:', event.request.url);
return response;
}
// Fetch and cache new resources
return fetch(event.request)
.then(response => {
// Don't cache non-successful responses
if (!response || response.status !== 200 || response.type !== 'basic') {
return response;
}
const responseToCache = response.clone();
caches.open(CACHE_NAME)
.then(cache => {
cache.put(event.request, responseToCache);
});
return response;
});
})
.catch(() => {
// Return fallback for images
if (event.request.destination === 'image') {
return caches.match('/images/fallback.png');
}
})
);
}
});
However, when I test it on an Android device, I get no Install prompt on either Brave or Chrome browsers.
If I manually go to "Add to home screen" it doesn't quite work as I hoped.
On Brave it presents me with two options: Install and Add a shortcut. Even when I select Install despite the screen saying 'Installing ..." it actually only creates a home screen shortcut.
On Chrome it both Installs or Adds a shortcut, depending on which option I select, but not without manually selecting.
What I really want is for Install to work as expected, i.e. to actually install the PWA like an app and a prompt to appear automatically for the user to start the install of the app.
On chrome on mobile devices, the install button doesn't appear every time. This depends on machine learning algorithm as explain here :
developer.chrome.com/blog/how_chrome_helps_users_install_the_apps_they_value
To help user to install the PWA without using "Add to home screen", you can try to use the event beforeinstallprompt.
There are some information here : https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Guides/Making_PWAs_installable#triggering_the_install_prompt
And next is an example of code from https://whatpwacando.today/installation
let deferredEvent;
window.addEventListener('beforeinstallprompt', (e) => {
// prevent the browser from displaying the default install dialog
e.preventDefault();
// Stash the event so it can be triggered later when the user clicks the button
deferredEvent = e;
});
installButton.addEventListener('click', () => {
// if the deferredEvent exists, call its prompt method to display the install dialog
if(deferredEvent) {
deferredEvent.prompt();
}
});