How we built push notification delivery for Safari users on Beams

Safari-notifications.png

Delivering push notifications to Safari is very different to other browsers. Find out how we implemented Safari support for Pusher Beams.

Introduction

In 2020, we added web browser support to Pusher Beams, enabling notification delivery to Chrome, Firefox, Edge and Opera. Safari was missing from this list, but we have recently released beta support so that you can send Safari push notifications to your users with Beams.

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

The Push API notifies the service worker when a new notification is received. This allows you to execute JavaScript in response to the notification, which can utilize any included data. For example, you could update your webpage to show an icon indicating a new message was received. We use this functionality to implement Pusher Beams insights features, such as delivery and open tracking.

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.

web browser notification via push api

Whereas notifications delivered to Safari appear like a standalone Mac app and are grouped together in the Notification Center as such.

Safari browser push notification

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

Summary

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.