v152 · enabled by default · notifications · pwa · macos
Notification attribution for PWAs on macOS
From Chrome 152 on macOS, notifications posted by an installed Progressive Web App are delivered through the PWA's own app shim and are natively attributed to the PWA — its own name and icon in Notification Center and per-app notification settings — instead of appearing under “Google Chrome”. The change also makes two behavioral adjustments that match WebKit: requireInteraction is no longer honored for installed PWAs (notification persistence is a per-app macOS user setting), and the app badging API now requires notification permission (silently doing nothing without it).
requireInteraction: trueis ignored for notifications attributed to an installed PWA — whether the alert stays on screen is now the user's per-app macOS setting, not the app's choice. Do not rely on persistent alerts for critical UX on macOS PWAs (details).navigator.setAppBadge()silently no-ops unless the PWA has notification permission — request permission before relying on the badge (details).- Admins who pre-grant notification permission via the Chrome
NotificationsAllowedForUrlspolicy must also deploy a macOS MDM configuration profile for each PWA's bundle ID, or the pre-grant stops working (details).
A chrome://flags entry #enable-mac-pwas-notification-attribution exists (macOS-only) for local testing of the pre-change behavior; the feature is enabled by default in 152 and the flag is tracked by about_flags.cc as “Route notifications for PWAs on Mac through the app shim, attributing notifications to the correct apps.”
at a glance
| What it is | A macOS platform integration change: PWA notifications are delivered by the PWA's app shim through UNUserNotificationCenter, so macOS attributes them to the PWA's own bundle (name, icon, per-app settings) instead of Chrome |
|---|---|
| Milestone listing | Chrome 152 — “Enabled by default” (milestone=152 listing, verified 2026-07-29; the listing is authoritative per gendn invariant #2) |
| Platform scope | macOS only, desktop only. The chrome://flags entry is compiled under BUILDFLAG(IS_MAC); ChromeStatus records no Android/WebView/iOS milestones |
| Applies to | Installed PWAs only — apps in install state INSTALLED_WITH_OS_INTEGRATION that have an app shim registered in the AppShimRegistry, and whose shim is ad-hoc signed (Chromium source, see requirements) |
| Web API surface | None new — the PSA calls the behavioral changes “not directly web-exposed”. The contract is behavioral: how Notifications and Badging behave for macOS PWAs |
| Runtime feature | base::Feature features::kAppShimNotificationAttribution, exposed at chrome://flags as #enable-mac-pwas-notification-attribution; enabled in Finch fieldtrial testing config 2026-07-08 (CL 8057884) |
| History | Dev trial desktop 130; ship desktop 152 (PSA estimated milestones) |
| ChromeStatus | 5863296436666368 — Notification attribution for PWAs on macOS (blink component UI>Notifications; tracking bug 327449602) |
syntax
This feature adds no new syntax — the existing Notifications and Badging entry points are the trigger surface, and attribution is decided by Chrome from the posting context:
// Triggers (unchanged web API surface):
new Notification(title, options); // page context
serviceWorkerRegistration.showNotification(title, options);
navigator.setAppBadge(contents); / navigator.clearAppBadge();
// Local testing switch (macOS only), compiled under BUILDFLAG(IS_MAC):
chrome://flags/#enable-mac-pwas-notification-attribution
Whether a given call is attributed depends on the requirements — the developer does not opt in or out per call.
Source: blink-dev PSA (“not directly web-exposed”); about_flags.ccwhy it exists
Before this change, every notification a PWA posted on macOS was displayed under the “Google Chrome” umbrella: Chrome's name, Chrome's icon, and Chrome's single entry in macOS notification settings. Users could not manage notification settings — sounds, badges, alert style, Focus modes — on a per-PWA basis, which the ChromeStatus motivation calls “a highly requested native integration on macOS”.
Routing delivery through the PWA's app shim (the small per-PWA .app bundle Chrome installs on macOS) gives each PWA its own identity with the operating system. Because macOS attributes a notification to the bundle that posts it, the PWA's name and icon appear in Notification Center and it gets its own entry in System Settings → Notifications, aligned with how native macOS applications behave.
how it works
The attribution is a delivery-path change inside Chrome and the app shim, verified against Chromium source:
- Routing. When a web page or service worker that maps to an installed PWA posts a notification, Chrome connects to a
MacNotificationProviderin the PWA's app shim process (AppShimManager::LaunchNotificationProvider(app_id)inapp_shim_manager_mac.h). If no shim is currently running, the call returns a remote connected to a dummy notification provider — the header documents a future change to instead launch the shim on demand. - Shim-side delivery. The shim runs its own
MacNotificationServiceUNbound toUNUserNotificationCenter.currentNotificationCenter(AppShimController::BindNotificationServiceinapp_shim_controller.mm). Because the request is posted from the shim's own process and bundle, macOS attributes it to the PWA. - Per-app OS permission. The app shim owns an operating-system-level notification permission of its own:
AppShimManager::ShowNotificationPermissionRequest(app_id)triggers the OS prompt shown by the shim, and the result drives the web permission flow (see permission model). - Badging.
AppShimManager::UpdateAppBadge(profile, app_id, badge)routes the app badge to the shim as part of the same integration (see app badging for the new permission gate).
Nothing in the Notifications or Badging web IDL changes. Web pages use the same Notification constructor, ServiceWorkerRegistration.showNotification(), and navigator.setAppBadge() calls as before; what changes is which process delivers them and which bundle macOS credits.
requirements: when attribution applies
Attribution is not unconditional. Chromium gates it on all of the following (WebAppTabHelper::GetAppIdForNotificationAttribution in web_app_tab_helper.cc, and AppShimController::WebAppIsAdHocSigned / ShouldCreateNotificationServiceUN in app_shim_controller.mm):
| Condition | Contract |
|---|---|
| Feature enabled | base::Feature kAppShimNotificationAttribution is on — enabled by default in Chrome 152 (Finch), toggleable at chrome://flags #enable-mac-pwas-notification-attribution |
| App installed with OS integration | The app's install state must be INSTALLED_WITH_OS_INTEGRATION; merely “locally installed” default apps are excluded |
| App shim exists | The app must be registered in the AppShimRegistry for the profile — i.e. a per-app shim bundle has actually been created |
| Shim is ad-hoc signed | The shim bundle's Info.plist key kCrAppModeIsAdHocSignedKey must be true; otherwise ShouldCreateNotificationServiceUN() returns false and no shim notification service is created. Ad-hoc signing is itself behind the separate #use-adhoc-signing-for-web-app-shims feature |
| macOS | The whole path is compiled under BUILDFLAG(IS_MAC); no other platform is affected |
If any condition fails, notifications fall back to the previous behavior: delivered by Chrome itself and attributed to “Google Chrome”.
Source: web_app_tab_helper.cc; app_shim_controller.mm; about_flags.ccthe two-layer permission model
With attribution active there are two permission layers for an installed PWA:
| Layer | Owner | Behavior |
|---|---|---|
| Web (origin) permission | Chrome content settings, per origin | Granted/denied via Notification.requestPermission() and Chrome's settings UI as before |
| OS (bundle) permission | macOS notification settings, per app shim bundle ID | The shim prompts via UNUserNotificationCenter; the user can also change it any time in System Settings → Notifications under the PWA's own name |
Chrome wires the layers together in the permission prompt path (permission_prompt_notifications_mac.cc): when the web permission prompt runs for an attributed app, Chrome first asks the shim for its OS-level result —
kPermissionGranted→ the web prompt is accepted.kPermissionPreviouslyDenied→ the web prompt is ignored (no prompt shown) and Chrome recordsNotificationsWasDeniedBecauseOfSystemPermissionin page-specific content settings.kPermissionDenied→ the web prompt is denied.
Practical consequence: once the user has denied the PWA at the macOS level, Notification.requestPermission() in that PWA no longer shows a prompt — recovery is only through System Settings → Notifications (or an MDM profile, for managed devices).
behavior contracts
The three developer- and administrator-facing contracts of this change each have a dedicated reference page:
requireInteractionnot honored for installed PWAs — notification persistence becomes a per-app macOS user setting; the web API field is ignored for attributed PWAs.- App badging requires notification permission —
navigator.setAppBadge()silently does nothing unless the PWA has notification permission. - Enterprise pre-grant now requires MDM — the Chrome
NotificationsAllowedForUrlspolicy must be paired with a macOS MDM configuration profile per PWA bundle ID.
Both web-facing changes deliberately match the already-shipping behavior of installed web apps in Safari on macOS, per the PSA (“Both of these changes match the already shipping behavior in WebKit”).
Source: blink-dev PSA — summary + interop sectionexamples
There is no new API to call — the change is behavioral. What a developer can do is (1) stop depending on requireInteraction for macOS PWAs and (2) gate badge updates on notification permission:
// Notifications: do not rely on requireInteraction persisting the alert
// for installed PWAs on macOS — the user's per-app setting decides.
const reg = await navigator.serviceWorker.ready;
reg.showNotification("Order ready", {
body: "Pick up at counter 3",
// Still fine to set for other platforms; ignored by macOS PWA attribution:
requireInteraction: true,
});
// Badging: macOS PWAs now silently ignore setAppBadge() without
// notification permission, so check first.
async function updateBadge(count) {
if (!("setAppBadge" in navigator)) return;
if (Notification.permission !== "granted") return; // macOS no-op guard
await navigator.setAppBadge(count);
}
ChromeStatus also links a Notifications API PWA-testing sample.
Source: blink-dev PSA — behavior changes; ChromeStatus sample linkweb platform tests
There is no WPT coverage specific to this change: the attribution is browser-shell behavior with no web-exposed surface to assert against, and the PSA describes the behavioral changes as “not directly web-exposed”. The host-API suites continue to exist and are unaffected in scope:
notifications/— constructor, event, and permission tests for the Notifications API.badging/—setAppBadge/clearAppBadgesuccess, error, and IDL harness tests. None assert a notification-permission gate (that gate is Chrome-on-macOS PWA behavior, not spec behavior).
browser compatibility
Interim table. BCD has no entry for the attribution behavior itself (it is browser-shell behavior, not an API member); the host APIs are covered. Rows below cite the linked BCD files verbatim, with the Chrome 152 macOS change annotated from the milestone listing and PSA.
| Browser | Support | Evidence |
|---|---|---|
| Chrome | 47 | BCD version_added: 47. 152 (macOS): ignored for installed PWAs with attribution — per-app OS setting controls persistence (PSA) |
| Edge | 17 | BCD version_added: 17; no separate statement on the macOS attribution change |
| Firefox | 117 (partial) | BCD: “Only supported on Windows. Behind a flag on other operating systems” (dom.webnotifications.requireinteraction.enabled) |
| Safari | No support | BCD version_added: false — WebKit does not implement the field; installed web apps on macOS use per-app OS settings (the behavior Chrome is aligning to, per the PSA) |
| Browser | Support | Evidence |
|---|---|---|
| Chrome | 81 | BCD notes: “Windows and macOS since Chrome 81. ChromeOS since Chrome 91. Linux offers no universal badging API on the operating system level.” 152 (macOS): requires notification permission for installed PWAs; silently no-ops without it (PSA) |
| Edge | 81 (mirror) | BCD edge: mirror; no separate statement on the macOS permission gate |
| Firefox | No support | BCD version_added: false |
| Safari | 17 | BCD: “Badging is supported for installed web apps on macOS Sonoma and higher”; passing 0 clears the badge instead of showing an unnumbered dot |
security and privacy
- Attribution is identity-strengthening, not a new channel. Notifications a PWA already could show are now credited to the PWA's own bundle; no new data leaves the device and no new web-exposed surface is added (the PSA calls the changes “not directly web-exposed”).
- Per-app OS control. Users gain macOS-level control per PWA — alert style, sounds, badges, Focus modes — under System Settings → Notifications, which they previously only had for Chrome as a whole (the stated motivation).
- OS denial wins. A PWA whose macOS-level permission was denied cannot re-prompt from the web;
Notification.requestPermission()is ignored and Chrome records the denial reason (NotificationsWasDeniedBecauseOfSystemPermission) for UI surfacing. - Signing boundary. Attribution only happens for ad-hoc-signed shims (
WebAppIsAdHocSigned()), so notification identity is tied to a shim bundle Chrome itself created and signed at install time. - Managed devices. Enterprise pre-grants now span two trust domains (Chrome policy + macOS MDM); see enterprise deployment for the exact requirements.
specifications
| Document | Status |
|---|---|
| Notifications API Standard (WHATWG) | Living Standard — unchanged by this feature; requireInteraction remains specified (“on devices with a sufficiently large screen, the notification should remain readily available until the end user activates or dismisses the notification”) |
| Badging API (W3C WICG) | Unchanged by this feature; the notification-permission gate is a Chrome-on-macOS platform constraint, not spec text |
| Chrome Enterprise policy — NotificationsAllowedForUrls | Existing policy; the macOS MDM profile is now additionally required for PWAs (see enterprise deployment) |
There is no specification document for the attribution mechanism itself — it is an implementation detail of Chrome's macOS app shim layer; the authoritative records are the PSA, the ChromeStatus entry, and the linked Chromium source.
Source: documents linked above, fetched 2026-07-29see also
- Chrome Platform Status — Notification attribution for PWAs on macOS (API record)
- blink-dev — Web-Facing Change PSA: Notification attribution for PWAs on macOS
- Chromium tracking bug 327449602
- MDN — Notifications API and MDN — Badging API (host APIs; neither documents this macOS attribution behavior — checked 2026-07-29)
- Chrome Platform Showcase — interactive demos for this feature
- googlechrome.github.io — Notifications API PWA-testing sample