Add to Home Screen Prompt: How the PWA Install Prompt Works on Android and iOS (2026)
Add to Home Screen Prompt: How the PWA Install Prompt Works on Android and iOS (2026)
The add to home screen prompt is the moment a progressive web app stops being a browser tab and becomes something with an icon on the user's device. It is also the step where most PWA install funnels leak, because the prompt behaves completely differently on Android and iOS, and neither behaviour is what developers expect the first time.
This guide covers what triggers the prompt, how to control it, why iOS has no prompt at all, and how to measure whether any of it is working.
Two platforms, two entirely different mechanisms
There is no single cross-platform "add to home screen" API. There are two unrelated systems that happen to produce a similar-looking icon:
|
|
Chromium browsers (Android, desktop) |
Safari on iOS and iPadOS |
|---|---|---|
|
Programmatic prompt |
Yes, via |
No |
|
Who initiates |
Your code, or the browser's own UI |
The user, manually |
|
Install path |
One tap in a browser dialog |
Share menu → Add to Home Screen |
|
Can you detect eligibility |
Yes |
Not directly |
Everything that follows is a consequence of that table.
The Chromium path: beforeinstallprompt
On Chromium browsers, when a site meets the installability criteria, the browser fires a beforeinstallprompt event instead of immediately showing its own UI. That event is the hook that lets you decide when to ask.
Installability criteria
Broadly, the browser expects:
- The site is served over HTTPS.
- A web app manifest is linked, containing at minimum a name or short name, a
start_url, adisplayvalue ofstandalone,fullscreenorminimal-ui, and icons — conventionally including 192px and 512px entries. - A service worker is registered. Chrome has historically required one with a
fetchhandler, though the precise requirements have shifted across releases. - The app is not already installed.
Because those details have changed between browser versions, do not treat any written list — including this one — as final. Verify against the current Chrome documentation and check the Application panel in DevTools, which reports the specific reason a site is not installable.
Controlling when the prompt appears
The default behaviour is rarely what you want, so the standard pattern is to intercept the event, stash it, and fire it later at a moment the user is actually engaged:
let deferredPrompt = null;
window.addEventListener('beforeinstallprompt', (e) => {
e.preventDefault(); // stop the browser showing its own prompt now
deferredPrompt = e; // keep it for later
showYourOwnInstallButton(); // your UI, your timing
});
installButton.addEventListener('click', async () => {
if (!deferredPrompt) return;
deferredPrompt.prompt(); // must follow a user gesture
const { outcome } = await deferredPrompt.userChoice;
trackInstallOutcome(outcome); // 'accepted' or 'dismissed'
deferredPrompt = null; // the event is single-use
});Three constraints trip people up:
prompt()must be called in response to a user gesture. Calling it from a timer or on page load will be rejected.- The event is single-use. Once prompted, that instance is spent; you need a fresh
beforeinstallpromptto ask again. preventDefault()without ever callingprompt()means the user never sees anything. If you intercept the event and then forget to surface your own button, you have silently disabled installation entirely. This is a genuinely common bug.
Confirming an install
window.addEventListener('appinstalled', () => {
hideYourInstallButton();
trackInstalled();
});The iOS path: there is no prompt
On iOS and iPadOS, Safari does not fire beforeinstallprompt and provides no API to trigger installation. The user must open the Share menu and choose Add to Home Screen themselves.
That leaves you with exactly one option: instructional UI. Detect that the user is on iOS Safari and not already in standalone mode, then show a small, dismissible hint pointing at the Share button with the two steps spelled out.
Practical notes:
- Keep it dismissible and remember the dismissal. A banner that returns on every page view is worse than no banner.
- Show it after some engagement, not on first paint.
- Since iOS 16.4, web apps launched from the home screen gained support for web push, which materially improved the case for installing at all.
- Third-party browsers on iOS have historically routed through the same underlying engine, so behaviour there tends to follow Safari rather than Chromium.
Detecting whether you are already installed
Both platforms support the same check, which is the basis of most install analytics:
const isStandalone =
window.matchMedia('(display-mode: standalone)').matches ||
window.navigator.standalone === true; // older iOS signalUse it to suppress install UI for users who already installed, and as the denominator for measuring how much of your traffic runs installed versus in a tab.
Why install prompts underperform
When an add to home screen prompt converts badly, the cause is usually one of these:
- Asked too early. A prompt on first paint, before any value has been delivered, is the single most common mistake.
- No stated benefit. "Install our app" is a request. "Get it on your home screen so it opens instantly offline" is a reason.
- Intercepted and never re-surfaced. See the
preventDefault()bug above. - Not installable at all. A manifest typo or a missing icon size silently prevents the event from ever firing. DevTools will tell you which.
- iOS treated like Android. No instructional UI means the entire iOS audience simply never installs.
Where the prompt fits in a wider distribution decision
The install prompt is the last step of a longer choice about how your app reaches users at all. If you are still weighing the trade-offs, PWA vs APK covers how Android distribution differs in practice, and PWA vs native app covers the broader cost, performance and distribution picture.
FAQ
Can I trigger the add to home screen prompt on iOS?
No. Safari on iOS provides no programmatic install API. The only option is instructional UI guiding the user through Share → Add to Home Screen.
Why is beforeinstallprompt never firing on Android?
Usually the site does not meet the installability criteria, or it is already installed. Open DevTools → Application → Manifest, which reports the specific blocking reason.
Can I show the install prompt more than once?
Each beforeinstallprompt event can be used once. You can prompt again if the browser fires a fresh event, but you cannot replay a spent one, and repeatedly nagging the same user is a good way to get your banner permanently ignored.
Does the user need a service worker for the prompt to appear?
On Chromium, a registered service worker has historically been part of the installability criteria, with the exact requirements varying by version. Check current documentation and the DevTools installability report rather than assuming.
How do I measure PWA installs?
Combine three signals: the userChoice outcome from your own prompt, the appinstalled event, and the standalone display-mode check on subsequent visits. The third is the most reliable, because it also captures installs that happened through the browser's own UI rather than yours.


