Concept in Notifications
Declarative Web Push
Published
Declarative Web Push lets a browser create and display a notification from a standard JSON push message without involving a service worker. A service worker can still process the message, while the declarative notification provides fallback content if that processing does not produce a replacement.
How it works
Section titled “How it works”The Push API exposes window.pushManager for a window-scoped subscription. The subscribe() options are optional: userVisibleOnly defaults to false, and applicationServerKey defaults to null. A user agent can require userVisibleOnly: true, and a push service can require a non-null applicationServerKey.
A declarative message has a top-level web_push value of 8030 and a notification object. The Push API requires title and navigate strings inside that object. navigate supplies the URL opened when the user activates the notification. Notification options such as body, lang, dir, tag, icon, and actions can also appear when they have the types defined by the specification.
Support
Section titled “Support”WebKit shipped Declarative Web Push for Home Screen web apps on iOS and iPadOS 18.4, then added it on macOS in Safari 18.5. WebKit documents the same JSON as a backwards-compatible payload: browsers with declarative support handle it directly, while other browsers can pass its notification object to showNotification() in a service worker (Meet Declarative Web Push, WebKit).
Examples
Section titled “Examples”A deployment can prefer a window-scoped subscription while retaining a registration-scoped manager and push handler for the fallback path.
Detecting a window-scoped push manager
Section titled “Detecting a window-scoped push manager”Check for Notification and window.pushManager before using the declarative subscription path. The fallback obtains a service worker registration and checks whether it has a pushManager. If neither manager is found, it returns null.
async function getPushManager() { if ('Notification' in window && 'pushManager' in window) { return window.pushManager; }
if ('serviceWorker' in navigator) { const registration = await navigator.serviceWorker.getRegistration(); if (registration && 'pushManager' in registration) { return registration.pushManager; } }
return null;}Pass the selected manager to the same subscribe() flow your application uses to obtain and store a PushSubscription.
Sending the standard JSON shape
Section titled “Sending the standard JSON shape”Create the payload on the application server, then send the serialized JSON through the existing Web Push delivery path. The browser validates navigate as a string and resolves its URL when creating the notification. Activation navigates to that previously validated URL.
const message = { web_push: 8030, notification: { title: 'Build completed', body: 'The production build is ready to review.', lang: 'en-US', dir: 'ltr', navigate: 'https://example.com/builds/482', },};
const payload = JSON.stringify(message);Send payload to the endpoint from the recipient’s PushSubscription. The browser can display the declared title and body and use navigate for activation.
Handling the same payload in a service worker
Section titled “Handling the same payload in a service worker”Keep a push handler for browsers that deliver the message to JavaScript. WebKit’s migration example takes the title from notification and passes the remaining members to showNotification().
self.addEventListener('push', (event) => { event.waitUntil((async () => { const { notification } = event.data.json(); const { title, ...options } = notification; await self.registration.showNotification(title, options); })());});With declarative support, the browser handles the standard payload. Without it, this handler displays the same notification data through the existing service worker path.
See also
Section titled “See also”- Push API: Declarative push message (W3C)
- Meet Declarative Web Push (WebKit)
- Web Push and PushManager.subscribe()
- Web Push on iOS and iPadOS
- Notifications API
Specifications
| Specification | Status |
|---|---|
| Web Push | W3C |
| Push API: Declarative push message | W3C draft |
- Legend
- Yes
- Partial
- Flag
- No
- Unknown
| Browser / Platform | Support | Versions | Confidence | Source | Notes |
|---|---|---|---|---|---|
| Chrome (Desktop)# | Yes | 42 | high | source | 1 |
| Chrome (Android)# | Yes | 42 | high | source | 23 |
| Edge (Desktop)# | Yes | 17 | high | source | 4 |
| Firefox (Desktop)# | Yes | 44 | high | source | 5 |
| Firefox (Android)# | Yes | 48 | high | source | 6 |
| Safari (macOS)# | Yes | 16 | high | source | 7 |
| Safari (iOS)# | Yes | 16.4 | high | source | 8 |
| Samsung Internet# | Yes | 4.0 | high | source | 910 |
| WebView (Android)# | No | — | high | source | 11 |
| Safari (iOS) · Declarative Web Push# | Yes | 18.4 | medium | source | 121314 |
- The `options` parameter with a `applicationServerKey` value is required.
- The `options` parameter with a `applicationServerKey` value is required.
- Derived by browser-compat-data mirroring from Chrome.
- The `options` parameter with a `applicationServerKey` value is required.
- From Firefox 72 onwards, can only be called in response to a user gesture such as a `click` event.
- From Firefox Android 79 onwards, can only be called in response to a user gesture such as a `click` event.
- Notifications are supported on macOS Ventura and later.
- Notifications are supported in web apps saved to the home screen.
- The `options` parameter with a `applicationServerKey` value is required.
- Derived by browser-compat-data mirroring from Chrome Android.
- No WebView Android support is recorded in browser-compat-data.
- WebKit's Safari 18.4 post: "Declarative Web Push is now available on iOS and iPadOS 18.4 for web apps added to the Home Screen." It describes Declarative Web Push as push notifications that can display without requiring a service worker.
- browser-compat-data has no Declarative Web Push entry. Its nearest key, `api.Window.pushManager`, records Safari on iOS 18.4 and is marked experimental.
- OpenPWA device test, 2026-10-20, iPhone 16 Pro, iOS 18.6.2 (22G100): `window.pushManager` is also exposed in a plain Safari tab; in a Home Screen app whose service worker is scoped to a subpath, `window.pushManager.getSubscription()` returned `null` while the worker's registration held a subscription, consistent with WebKit's statement that only a root-scoped worker shares the window's subscription.
Ecosystem & commercial policy
| Entity | Type | Context | Status | Sponsored | Notes |
|---|---|---|---|---|---|
| Apple Push (APNs)# | delivery_policy | iOS | Partial | No | iOS Web Push requires the user to add the app to the Home Screen first. |
Try it
Run this capability in the OpenPWA demo app: /demo/#push