Implementing Safari support required significant additional development work compared to the other browsers, and in this blog post we will discuss the differences between sending notifications to browsers using the Web Push API and Safari.
The vast majority of browsers support the Web Push API (including Chrome, Firefox, Edge and Opera). If you implement support for this web standard then you will be able to send notifications to most desktop browsers – and many browsers on Android. You don’t have to add anything to your code to support specific browsers.
Safari on macOS does not support the Push API and instead Apple opted to develop their own push notification implementation which is closer to the notification experience of a macOS app. It uses Apple’s push notification gateway, APNs, which will be familiar to those who develop apps for iOS and macOS. Note: Safari on iOS doesn’t support any kind of browser notification at all, and that’s the same for all third party browsers on iOS.
While there are a lot of similarities when it comes to user experience, there are key technical differences in implementing Safari support, the most significant being the steps you have to take when registering for notifications and the actions you can take upon receiving a notification.
Registering for push notifications
The Push API centers around service workers. First, you must register a service worker for your web app. You can then request notification permission from the user, passing your VAPID public key from your sever (see below). You then get credentials back that you can pass to your server to use when sending notifications.
VAPID keys are essentially a public and private key pair generated on your server and are used as part of the VAPID specification, which allows the push gateway to verify your server’s identity. The public key is passed to the browser in order to tie each subscription to your key, so only you can publish notifications to those users. The keys never expire and are free to generate.
Safari doesn’t use service workers for push notifications. When requesting notification permission in Safari, you pass the URL of your web service. You must implement the web service with a number of specific endpoints which Safari will automatically make requests to during the registration process. Safari uses these endpoints to:
Request the “push package”
Notify your server of new subscribers/removed subscribers
Log errors regarding the push package and registration process
A push package is a zipped directory containing your web app’s icon in several sizes, plus a JSON file containing details about your web app. You must cryptographically sign the files using a certificate obtained from Apple (see below). This zip file is downloaded by Safari every time the permission dialog is shown. We found the implementation of the web service and push package generator to be the most complicated part of adding Safari support to Beams. It is completely different to the Push API and therefore there wasn’t much code to be reused from our Push API (or iOS) implementation.
You must use an Apple-issued certificate to sign push packages and authenticate when publishing notifications to Safari. The certificate proves ownership of an identifier for your web app called a “website push ID”. To register a “website push ID” you must have a paid Apple Developer program membership. The certificate expires after a year and therefore requires yearly renewal.
It is possible to publish Safari notifications using an authentication token signing key rather than a certificate, which is desirable because the key never expires. However it is still necessary to use the certificate when signing push packages and as a result we have to ask customers for their certificate for Safari, rather than their key.
Interacting with/responding to notifications
Safari doesn’t use service workers and it isn’t possible to execute any code in response to receiving a notification. This means it wasn’t possible for us to implement delivery tracking for Safari browser notifications. However we do have some ideas for future changes to support open tracking.
For Push API notifications, the developer generally has more control over what happens when a notification is clicked. For example, it is possible to just hide the notification. Safari on the other hand is more limited when it comes to notification functionality, and always requires a URL to be opened when a notification is clicked.
Displaying Safari notifications
Visually, notifications displayed by Safari are slightly different compared to other browsers on a Mac.
Notifications delivered via the Push API are displayed as a “sub notification” of the browser.
Whereas notifications delivered to Safari appear like a standalone Mac app and are grouped together in the Notification Center as such.
On a Mac, Safari notifications are delivered when the browser is closed, whereas Push API browsers only appear to deliver notifications when the browser is running (but the page does not have to be open).
There is less customization available for Safari notifications compared to Push API notifications (and iOS notifications). For example, it isn’t possible to include an image in a Safari notification, other than your web app’s icon. This means we aren’t able to offer rich notifications for Safari in the same way we can for mobile apps or other browsers.
Apple have not updated Safari notifications for a long time. We’d love to see richer notification opportunities for Safari users in the future so that we can offer the same notification experience across all browsers we serve. We’ll be sure to stay on top of any new customization functionality should it arise
There are many differences when sending notifications to Safari compared to Push API browsers. Implementing Safari support was a surprisingly complicated process: we found there to be little overlap between the Push API and Safari in terms of our internal implementation.
The good news is that Pusher Beams now has Safari support and we’ve been able to hide most of the complexity for developers by:
We provide a unified API for triggering notifications to Push API browsers and Safari – you can send to both with a single API call (as well as to iOS/Android)
We provide a single client SDK that supports Chrome, Firefox, Edge, Opera and Safari.
We hide all the complexity of generating and serving push packages, including the resizing of icons.
We store your credentials and manage browser tokens
We handle the nuances of publishing to APNs at scale
You can read about how to get started with Pusher Beams and give feedback on the beta program here.