Platforms · Platform
PWAs on iOS and Safari
Published Updated
On iOS and iPadOS a PWA is a Home Screen web app: the user adds the site from the Share sheet, and from then on it opens outside the browser with its own App Switcher entry, and can use service workers, Web Push, and badging if the site implements them. There is no programmatic install step, so the platform work is teaching the gesture and designing for what WebKit ships in each release.
How it works
Section titled “How it works”Three OS releases define the behaviour a site sees: iOS 16.4 (2023-03) made third-party browsers and manifests part of the flow, iOS 18.4 (2025-03) added Declarative Web Push, and iOS 26 (2025-09) made “open as a web app” the default for every added site.
The Add to Home Screen gesture
Section titled “The Add to Home Screen gesture”Apple’s iPhone guide Turn a website into an app in Safari on iPhone documents the path in Safari (English UI): tap the Share button, scroll the list of actions, tap Add to Home Screen, leave Open as Web App turned on, then tap Add. If Add to Home Screen is missing from the sheet, the user restores it through Edit Actions at the bottom of the list. The icon exists only on the device where it was added.
Since iOS and iPadOS 16.4 a third-party browser can offer the same action if, per the
WebKit announcement,
the app holds the com.apple.developer.web-browser managed entitlement, a WKWebView
showing an http: or https: document is in the Share sheet’s activityItems, and the
device is not a Shared iPad.
What decides web app versus bookmark
Section titled “What decides web app versus bookmark”On iOS 16.4 through 18 the manifest decided: a site whose manifest set display to
standalone or fullscreen opened as a web app no matter which browser added it, and a
site without such a manifest (and without the legacy web-app-capable meta tag) became a
Home Screen bookmark that opens in the user’s default browser.
iOS 26 and iPadOS 26 moved the decision to the user. WebKit’s
Safari 26.0 notes state
that by default every website added to the Home Screen opens as a web app, that the user
can disable “Open as Web App” while adding to get a bookmark instead, and that there are
“zero requirements for installability” in Safari. A manifest still shapes the result: icons
declared in it are used, and display, name, and start_url apply.
Icons and identity
Section titled “Icons and identity”Manifest icons have been read since iOS 15.4, but an apple-touch-icon link takes
precedence when both are present. With no icon at all, iOS 16.4 and later draw a monogram
from the first letter of the site’s name on a colour taken from the site. The manifest
id member (16.4+) is combined with the name the user typed at add time to tell multiple
installs of one site apart, which is what lets Focus silence one copy and not another.
APIs gated to the installed context
Section titled “APIs gated to the installed context”Web Push, the Notifications API, and the Badging API work in Home Screen web apps from
iOS 16.4; a Safari tab on iOS has none of them. Notification permission must be requested
in response to a user gesture such as a tap on a subscribe button, and setAppBadge()
changes the stored count even before permission is granted, showing it on the icon once
notifications are allowed. Declarative Web Push (iOS and iPadOS 18.4, macOS 15.5) adds
window.pushManager and displays notifications without a service worker; the original
push flow still subscribes through a service worker registration.
Storage
Section titled “Storage”Browser-stored data is best-effort unless the origin calls navigator.storage.persist(),
and Safari answers that call from the user’s interaction history without showing a prompt.
With cross-site tracking prevention on, Safari deletes an origin’s script-created data
after seven days of browser use with no tap or click on that origin; cookies set by the
server survive (MDN,
Storage quotas and eviction criteria).
From iOS 17 a Home Screen web app gets the browser-app quota of about 60 % of the disk per
origin, not the 15 % an embedded WKWebView gets.
Examples
Section titled “Examples”Both snippets run in a Safari tab and in the Home Screen web app; the branches are what differ.
Subscribing to push with the declarative manager first
Section titled “Subscribing to push with the declarative manager first”Which PushManager the page gets depends on the flavour available. The declarative one
hangs off window and needs no service worker; the original one lives on a registration
and has to wait for an active worker.
subscribeButton.addEventListener('click', async () => { if (!('PushManager' in window) || !('Notification' in window)) { // A Safari tab on iOS, or any browser without push: offer an in-app inbox. showInAppInbox(); return; }
let pushManager; if ('pushManager' in window) { pushManager = window.pushManager; // Declarative Web Push, iOS 18.4+ } else if ('serviceWorker' in navigator) { await navigator.serviceWorker.register('/sw.js'); pushManager = (await navigator.serviceWorker.ready).pushManager; } else { showInAppInbox(); return; }
if ((await Notification.requestPermission()) !== 'granted') return;
await pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: VAPID_PUBLIC_KEY, });});WebKit rejects a subscription without userVisibleOnly: true, as Chrome and Edge do. The
declarative path also requires the declarative JSON payload on the server side; see
iOS Safari push.
Showing the install hint only in a browser tab
Section titled “Showing the install hint only in a browser tab”The display-mode media feature reports the current presentation, not how the page was
launched, so test for the one mode an install hint belongs in rather than listing the
modes it does not.
const inBrowserTab = typeof window.matchMedia === 'function' && window.matchMedia('(display-mode: browser)').matches;
if (inBrowserTab) { // No install event exists on iOS: explain Share > Add to Home Screen yourself. showAddToHomeScreenHint();} else { // Home Screen web app, fullscreen, or an engine that cannot answer: no hint. hideInstallHint();}A page that entered fullscreen through the Fullscreen API also stops matching browser,
which is the right outcome here: an overlay on top of a fullscreen video is worse than a
missed hint.
Observed behaviour
Section titled “Observed behaviour”beforeinstallprompt is listed by MDN with no Safari or Safari on iOS version, so the only
install UI is the Share sheet, whose labels changed with iOS 26.
Because the switch is per add, two users can add the same URL and get different
behaviour; detect display-mode at runtime instead of assuming the manifest won.
See also
Section titled “See also”- iOS Add to Home Screen
- iOS Safari push
- Badging
- Storage persistence
- PWAs on Safari for macOS (Dock apps)
- Web Push for Web Apps on iOS and iPadOS (webkit.org)
- Meet Declarative Web Push (webkit.org)
- WebKit Features in Safari 26.0 (webkit.org)
- Turn a website into an app in Safari on iPhone (support.apple.com)
Specifications
| Specification | Status |
|---|---|
| None. | |