Web push notifications allow users to opt-in to asynchronous messages from a server to a web application. The message can be sent at any time, even when the web application or the web browser is inactive. This W3C standard, based on the HTTP/2 protocol, is now supported by Chrome, Firefox, Edge, Opera, and Safari – but not by iOS.
In this blog post, I will discuss a minimal working example for implementing Web Push. The source code for the client application running in the web browser is available on GitHub. If you want to skip the technical stuff and just try it, a working sample for testing and sending push messages can be viewed here.
Web Push: Client Side
The workflow for subscribing to Web Push messages is as follows: as a prerequisite, a VAPID key pair has to be created, consisting of a public and a private key. A Web site or locally installed PWA can now request permission from the user to send messages to the web client. If this is allowed, the client application sends the public VAPID key, also called the applicationServerKey
, to the push service that is defined for the web browser or web engine in use. Every browser uses its own push service but this is transparently taking care of when using the API. This is a code example for getting the permission and retrieving the subscription information:
The push service returns the subscription information: an endpoint URL, an authorization key to authorize at the push service and a public encryption key to encrypt the message payload. The client application transmits this information to the Web server to be stored. This information looks like this (keys and URL abbreviated):
{ "endpoint": "https://updates.push.services.mozilla.com/wpush/v2/gAAAAA...", "keys": { "auth": "wvlsArhzWhluC2rHaMt8YA", "p256dh": "BNWCKg1oxCstDq6V18RHI4ZiUA2GycC7k3S5H4MnishiQkw62Zy0elt9z..." } }
Web Push: Server Side
To send a push message the server encrypts the message payload with the p256dn
key, signs it with the private VAPID key, and contacts the push service via the endpoint
URL, authorizing with the auth
key. To do this heavy lifting there are already quite a few libraries available, e.g. for Node.js, PHP, Python, and many other programming languages. Some of them are listed below.
As an example, we can do this with the Node.js library web-push
and after installing the library with
npm -install web-push
you can use the following source code to send push messages:
The get valid keys and the endpoint URL, head over to the working client demo and subscribe to push messages. Don’t forget to allow push messages, when asked! Then replace the code for the definition of the variable pushSubscription
with the content of the subscription data text field at the top of the page and also replace vapidKeys.publicKey
and vapidKeys.privateKey
with the respective VAPID keys at the bottom of the page. Running the code should now send a push message with the defined payload text.
Back to the Client
The push service sends the message to the client web browser or web engine. During the subscription process, the web page or PWA has to register a so-called service worker, a Javascript file that can run independently in the background. This service worker contains an event listener responsible for the display of the message. The basic code looks like this:
The showNotification function accepts an options
object with many possible parameters, including an icon to be shown or a vibration pattern. Especially useful is the definition of action buttons to trigger events like opening a web page. See the demo code on GitHub for an example.
According to the Google documentation for Web Push, this API opens a whole new set of possibilities for you to re-engage with your users. Whether or not you share this optimism, push notifications are surely an interesting alternative or at least a complement to other methods like email newsletters.
Where to go from here
Web Push Notifications
W3C Working Draft: Push API
Can I use Web Notifications?
Demo source code on GitHub
Demo App for Web Push
VAPID key generator
Push Companion
Libraries for sending Web Push messages
Node.js: web-push
PHP: web-push-php
Java: webpush-java
C#: web-push-csharp
Python: pywebpush