Skip to content

iOS Add to Home Screen: PWA installation on iOS

Published Updated

In one line: On iOS and iPadOS the only way to install a PWA is the user’s own gesture — tap Share, then “Add to Home Screen”. There is no install event to hook and no prompt you can trigger. Your markup supplies defaults and assets — icons, a default name, a manifest — while the user edits the name while adding and, on iOS 26, decides with the “Open as Web App” switch how the icon launches.

Since the first iPhone, users could add any website to the Home Screen. In Safari on iOS and iPadOS the flow is: tap the Share button to open the Share menu, then tap “Add to Home Screen”. The icon for that website then appears on the Home Screen, and a quick tap returns the user to the site. Users are also given the opportunity to change the app’s name while adding it.

There is no programmatic alternative. beforeinstallprompt — the event other platforms fire before a user is prompted to install a site to a home screen — is non-standard and marked limited availability, so there is nothing to intercept, defer, or re-fire here.

In iOS and iPadOS 16.4, third-party browsers gained the ability to offer “Add to Home Screen” from the Share menu. WebKit documents exactly what an app must satisfy for the item to appear:

  • the application holds the com.apple.developer.web-browser managed entitlement,
  • a WKWebView is included in the Share menu’s activityItems array,
  • that WKWebView is displaying a document with an HTTP or HTTPS URL, and
  • if the device is an iPad, it is not configured as a Shared iPad.

What happens when the user taps the resulting icon changed materially between 16.4 and 26.

On iOS and iPadOS 16.4, any website with a manifest whose display member is standalone or fullscreen opens as a web app — no matter which browser added it — with its own preview in the App Switcher, separate from Safari. With no manifest requesting web app behaviour and no meta tag marking the site as web-app-capable, the entry is saved as a Home Screen bookmark, and from 16.4 those bookmarks open in the user’s current default browser.

On iOS 26 and iPadOS 26, WebKit revised this. By default every website added to the Home Screen opens as a web app. A user who would rather have a browser bookmark can disable “Open as Web App” while adding — even if the site is configured to be a web app. WebKit’s framing is blunt: there are now zero requirements for “installability” in Safari, and users can add any site to their Home Screen and open it as a web app. The decision moved from your markup to the person holding the phone.

This did not remove support for anything. WebKit is explicit that manifest benefits still apply — declare your icons in the manifest and they are used — and that giving users a web app experience simply no longer requires a manifest file, much as Home Screen web apps on iOS and iPadOS never required service workers the way PWAs do on other platforms.

  • Manifest icons have been supported since iOS and iPadOS 15.4. You can also use the long-supported technique of listing apple-touch-icon links in the document head — and if you do both, apple-touch-icon takes precedence over the manifest-declared icons.
  • Ship no icon and the system invents one. Where iOS previously generated an icon from a screenshot of the site, 16.4 creates a monogram icon from the first letter of the site’s name plus a colour taken from the site.
  • Size the touch icons. Apple’s guide has you place an apple-touch-icon.png in the root document folder for a whole-site icon, or declare per-page icons with sizes; the icon closest to the device’s appropriate size is used, falling back to the smallest icon larger than that size, and then to the largest icon available.
  • Launch image. By default a screenshot of the web application from its last launch is used while it starts; <link rel="apple-touch-startup-image" href="/launch.png"> overrides it. This matters most when the web app is offline.
  • Launch icon title. The <title> tag is used by default; <meta name="apple-mobile-web-app-title" content="AppTitle"> sets a different one.
<!-- Icon for the whole site, plus a device-specific override -->
<link rel="apple-touch-icon" href="/touch-icon-iphone.png">
<link rel="apple-touch-icon" sizes="180x180" href="/touch-icon-iphone-retina.png">
<!-- Launch image shown while the web app starts -->
<link rel="apple-touch-startup-image" href="/launch.png">
<!-- Name under the Home Screen icon -->
<meta name="apple-mobile-web-app-title" content="AppTitle">

Apple’s archived guide describes the pre-manifest mechanism, and it is worth understanding because you will meet it in old code and old advice:

Set the apple-mobile-web-app-capable meta tag to yes to turn on standalone mode.

In that archived model, standalone mode means Safari is not used to display the web content — no URL field at the top, no button bar at the bottom, only the status bar — and apple-mobile-web-app-status-bar-style “has no effect unless you first specify standalone mode”. WebKit’s own history places this tag in August 2008 with iPhone OS 2.1, with Web Application Manifests standardised from 2013 and adopted by Safari in March 2018 with iOS 11.4.

Read that dependency as the documented legacy behaviour, not as a rule that still decides standalone mode today: on iOS 26 and iPadOS 26 the “Open as Web App” switch is what determines whether the Home Screen entry opens as a web app, whatever the markup says.

<!-- Legacy standalone mode, as documented in Apple's archived guide -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<!-- "black" is the value Apple's archived guide demonstrates -->

You cannot ask whether the user can install — there is no install event. What you can ask is how the page is being displayed right now, and that is the branch that matters. Two checks exist:

  • window.navigator.standalone is the read-only Boolean property Apple’s guide documents for determining whether a webpage is displaying in standalone mode.
  • The standard display-mode media feature tests whether a web app is being displayed in a normal browser tab or in some alternative way such as a standalone app or fullscreen. Its value identifies the mode the browser actually applied, which may differ from the one the manifest asked for.
// Prefer the standard media feature; fall back to Apple's legacy property.
const standalone =
('standalone' in window.navigator && window.navigator.standalone === true) ||
window.matchMedia('(display-mode: standalone)').matches;
if (standalone) {
hideInstallHint(); // displaying standalone — nothing to teach here
} else {
// No install event exists on iOS, so the only "prompt" is your own copy.
showShareMenuInstructions(); // "Tap Share, then Add to Home Screen"
}

Show that hint after a couple of visits rather than on first load, and never render it while the page is displaying standalone — an install banner inside a launched web app is pure noise.

Capability support for Home Screen web apps

Section titled “Capability support for Home Screen web apps”
Capability iOS / iPadOS Notes
Add to Home Screen Yes, from the Share menu Safari since the first iPhone; third-party browsers from 16.4.
beforeinstallprompt No Non-standard, limited availability — no programmatic install.
Opens as a web app Yes Manifest display: standalone/fullscreen on 16.4; default for every added site on iOS 26.
App Switcher entry Yes The web app previews separately from Safari.
Service workers Yes, not required Home Screen web apps never required one; original Web Push does, Declarative Web Push (18.4+) does not.
Web Push Yes (16.4+), Home Screen web apps Request must respond to direct user interaction. Declarative Web Push adds window.pushManager from 18.4.
Badging API Yes (16.4+), Home Screen web apps Count appears on the icon once notifications are allowed.
Manifest id Yes (16.4+) Combined with the user-chosen name to identify each install.
Manifest icons Yes (15.4+) apple-touch-icon takes precedence if both are present.
Screen Wake Lock / Screen Orientation / User Activation Yes (16.4+) Listed by WebKit as new for web app developers in 16.4.
Persistent storage by default No Storage is best-effort unless the origin opts in.

For per-feature figures across every browser, see /compatibility/.

Multiple installs are a feature, not a bug

Section titled “Multiple installs are a feature, not a bug”

iOS has supported installing the same web app more than once since the very beginning, and WebKit frames it as deliberate: multiple accounts, work versus personal, and so on. From 16.4 the manifest id member — a URL-shaped unique identifier for the web application — is combined with the name the user typed when adding it, so each copy is distinguishable. That is what lets Focus silence notifications from “Shiny (personal)” while allowing “Shiny (work)”, and what syncs Focus settings across devices when the user gives the same site the same name on each.

Declaring id explicitly is still worth doing: web.dev’s point is that an explicit id defines the identifier outright, removing its dependence on start_url or where the manifest happens to live.

  • Ship your own “tap Share, then Add to Home Screen” instructions — no browser UI prompts for you.
  • Branch on (display-mode: standalone) (with navigator.standalone as the legacy fallback), never on the user agent string.
  • Declare icons in the manifest and know that a stray apple-touch-icon will override them.
  • Set a manifest id so multiple installs stay distinguishable and Focus settings sync.
  • Do not rely on apple-mobile-web-app-capable to decide web app mode on iOS 26 — the user’s “Open as Web App” switch does.
  • Register a service worker even though the Home Screen entry does not require one; original Web Push (16.4+) does. Declarative Web Push (18.4+) subscribes through window.pushManager without one.
  • Treat stored data as best-effort: it survives while the origin is under quota, the device has space, and the user has not cleared it — and, with cross-site tracking prevention on, Safari proactively deletes script-created data for an origin with no click or tap in the last seven days of browser use. navigator.storage.persist() is the opt-in, and Safari answers it automatically from interaction history without showing the user a prompt.
  • Test on real hardware — the behaviours above are Home Screen behaviours, not tab behaviours.
  • PWAs on iOS and Safari — the whole WebKit platform picture once the app is on the Home Screen.
  • iOS Safari push — the 16.4 Web Push setup that depends on this install step.
  • Badging — setAppBadge/clearAppBadge on the Home Screen icon.
  • Installability criteria — what other platforms require before they will offer an install at all.