Manifest protocol_handlers: registering a PWA for custom URL schemes
Published
In one line: the manifest’s protocol_handlers member registers an installed PWA as
the OS’s handler for a URL scheme (like mailto: or a custom web+-prefixed one), so
clicking a matching link — from a browser tab, another app, or the OS — launches your app
with that URL instead of just navigating a page.
What it is
Section titled “What it is”Per MDN, protocol_handlers is an array of objects, each with a required protocol
(the scheme to handle, e.g. mailto, ms-word, or web+jngl) and a required url (an
HTTPS URL within the app’s scope where the %s token is replaced with the full clicked
URL). Registering the association with the OS usually happens at install time, though per MDN
it can also be made afterward for an already-installed app.
Where it is supported
Section titled “Where it is supported”- Legend
- Yes
- Partial
- Flag
- No
- Unknown
| Browser / Platform | Support | Versions | Confidence | Source | Notes |
|---|---|---|---|---|---|
| Chrome (Android) | No | — | medium | source | 1 |
| Chrome (Desktop) | Yes | 96 | medium | source | — |
| Edge (Desktop) | Yes | 96 | medium | source | — |
| Safari (iOS) | No | — | medium | source | 2 |
| Safari (macOS) | No | — | medium | source | 3 |
| Firefox (Desktop) | No | — | medium | source | 4 |
| Samsung Internet | No | — | medium | source | 5 |
- Desktop-only registration.
- Safari does not implement the `protocol_handlers` manifest member (MDN compatibility table, checked 2026-10-03).
- Safari does not implement the `protocol_handlers` manifest member (MDN compatibility table, checked 2026-10-03).
- Desktop Firefox does not install web apps from the manifest and does not implement `protocol_handlers` (MDN compatibility table, checked 2026-10-03).
- Chromium ships manifest protocol handlers for desktop installs only; Samsung Internet lists no support (MDN compatibility table, checked 2026-10-03).
Manifest-based protocol_handlers registration is desktop-only across the browsers that
implement it; there is also the separate, older navigator.registerProtocolHandler() API
for registering a handler imperatively from a page, which does not require installation.
How to use it
Section titled “How to use it”Declare the protocol and the URL template in the manifest:
{ "protocol_handlers": [ { "protocol": "web+coffee", "url": "/coffee?type=%s" } ]}Separately, MDN documents a naming rule for the related, older
navigator.registerProtocolHandler() API: its scheme argument must begin with web+
followed by one or more lower-case ASCII letters (e.g. web+coffee), or be one of a fixed
safelist such as mailto, bitcoin, or magnet. The manifest’s protocol_handlers page
itself does not document a naming restriction on its protocol field.
Once installed and registered, the %s placeholder in the handler URL is replaced by
the URL that starts with the handler’s scheme.
How to detect it at runtime
Section titled “How to detect it at runtime”Per MDN, associating a protocol with an installed app is usually done during installation,
though the association can also be made afterward for an already-installed app. What a
page can detect is whether the separate, imperative registerProtocolHandler() method
exists, for sites that want to offer registration outside of installation:
if ('registerProtocolHandler' in navigator) { navigator.registerProtocolHandler('web+coffee', '/coffee?type=%s');} else { // No imperative registration API — rely on the manifest-declared // protocol_handlers association completed at install time instead.}What goes wrong
Section titled “What goes wrong”- Manifest-based
protocol_handlersregistration only takes effect once the app is installed — it does not register anything for a page opened in a plain browser tab. - MDN’s documented
web+-prefix / safelist naming rule applies to the olderregisterProtocolHandler()API’sschemeargument — its manifestprotocol_handlerspage does not itself state thatprotocolvalues are restricted the same way. - The
urlmember must be within the app’s manifest scope and use HTTPS, per MDN — it cannot point off-origin. - The
%splaceholder is replaced with the entire clicked URL, not just a parsed payload — parse out the part after the scheme yourself in the handler route.
Where to go next
Section titled “Where to go next”- manifest: file_handlers support — another manifest member that registers an installed PWA with the OS, for file types instead of URL schemes.
- Handle files — a related guide to registering an installed PWA for OS-level file associations.