Sending push notifications with Safari 16 on macOS Ventura

Kevin Basset
5 min readJan 5, 2023

Good news for developers using Safari 16 on macOS Ventura: you can now send web push notifications directly through Safari 16 without the need for a paid Apple Developer Account or a custom .P12 certificate.

Safari 16 on macOS Ventura now directly supports the Web Push API!

This is a major win for developers, as it shows Apple’s (new?) commitment to following W3C specifications. But don’t get too excited just yet — there are still a few things to watch out for to ensure everything runs smoothly. This article will fill you in on all the details.

Detecting Safari

To detect if a device is using Safari, you probably used the navigator.userAgent JavaScript property. This property returns a string that represents the user agent of the browser.

Before this new update, at Progressier, I would use the code below to detect Safari. Because I knew Safari didn’t support web push notifications, I could simply update my UI and logic accordingly.

if (navigator.userAgent.indexOf('Safari') !== -1 && navigator.userAgent.indexOf('Chrome') === -1) {
// the device is using Safari
} else {
// the device is not using Safari
}

Detecting Compatibility with the Web Push API

However, now that all devices running Safari 16 on macOS Ventura or higher support the Web Push API, we need a new method that checks whether the device is actually compatible with that API.

In other words, instead of relying on browser detection, you must now switch to feature detection to ensure you prompt users that have a compatible browser to allow push notifications when required.

if (navigator.serviceWorker && window.PushManager && window.Notification) {
// the device supports the Web Push API
} else {
// the device does not support the Web Push API
}

This is what the code snippet above does:

  • navigator.serviceWorker checks that the device has support for Service Workers, which is a required part of the Web Push API.
  • window.PushManager verifies that the device has support for the PushManager interface, which is also a required part of the Web Push API.
  • And last but not least, window.Notification ensures that the device has support for the Notification API.

If a user’s browser supports all three, then you should be able to send push notifications to them.

User action required

One of the main differences between Apple’s implementation and that of the rest of the browser vendors is that you must wait for a user gesture (= a click) to trigger the push prompt.

If you attempt to ask users to allow push notifications outside of a click event listener, this is what you’ll get:

No prompt will be shown if you programmatically request users to allow push notifications outside a click event listener

If anything, that’s a good thing. I’m sure you’ve stumbled upon one of those annoying news websites asking you to allow notifications as soon as the page has fully loaded. Everybody hates those. Well, on Safari 16, they‘re not able to do that.

Even if you use push notifications properly, you may need to update your setup if you didn’t previously ask users to allow notifications from within a click event listener. I personally didn’t, and I’m guessing that most developers probably didn’t either.

Here is an example of how you might request permission to send push notifications from within a click handler in JavaScript:

document.getElementById('myButton').addEventListener('click', function() {
// Check if push notifications are supported and allowed
if (navigator.serviceWorker && window.PushManager && window.Notification) {
// Request permission to send push notifications
navigator.serviceWorker.getRegistration().then(function(registration) {
registration.pushManager.subscribe({ userVisibleOnly: true }).then(function(subscription) {
console.log('Push notifications are allowed.');
//save the push subscription in your database
}).catch(function(error) {
console.log('Error:', error);
});
});
}
});

At Progressier, I designed a Push Button that takes care of the whole logic for you:

  • it‘s greyed out on devices that don’t support the Web Push API
  • it saves the push subscription in your database against their user profile (so you can sync user emails with their push subscriptions for example)
  • the wording of the button is updated after the user has allowed or blocked push notifications
Your button to request notifications should sync with the actual status of push notifications in the browser

Tell users how to update their preferences after allowing/blocking notifications

You should also tell users how they can update their notifications status. Not everyone knows the functionality can be accessed by clicking on the padlock icon in the URL bar (and in some browsers — that’s in fact not where permissions are).

Also, in the case the user has accidentally allowed or blocked notifications, you should walk them through the process of changing their preferences.

Updating push preferences on Chrome

For example, when a user clicks the Progressier Subscribe Button after they’ve blocked notifications, it shows them how to allow notifications again.

This is useful because you can’t programmatically trigger the push prompt again once they’ve blocked notifications (also a blessing — just imagine all the spam prompts we’d get otherwise).

Updating push preferences on Safari 16+

On Safari, the little padlock icon in the URL bar does not allow you to change your push notification preferences. So your UI must show a different set of instructions depending on whether the user browses your app using Chrome or Safari (use the method above to detect Safari).

To update your push preferences on Safari 16, you must go to Safari > Settings > Websites. Then scroll to Notifications in the General tab. In the right-hand panel, you’ll see a list of domains for which you’ve allowed or blocked notifications. Use the toggle to update it.

Conclusion

Apple finally following the W3C specs is awesome news for the web. Their implementation is very close to that of Chrome, Firefox, and Edge with only a few differences:

  1. Switch to feature detection instead of browser/device detection (which will also prepare you for notifications coming to iOS in 2023).
  2. Wait for a user action to prompt your users to allow push notifications (or they won’t be prompted at all on Safari).
  3. Tell users how to update their preferences in Safari after they’ve allowed or blocked notifications

If you have comments or questions, reply below or hit me up at Progressier!

--

--

Kevin Basset

founder @ progressier.com — everything you need to distribute your web apps without constraints