React Push notifications (with hooks)

How Push notifications work and how to in React

This article is a guide to create Push notifications with React using Hooks. By the end of it you will create a working Push notifications system. In the meantime, you can play with the demo or browse the source code of the final result.

I recently wrote an article about Web Push Notifications in vanilla JavaScript, and this is the React version. I suggest you read that article if you want to know the theory and flows of the Push Notifications so that we can jump straight to the code.

This article is divided into two parts:

Handling the Push Notification Handling the React app

Handling Push notifications

Photo by Tim Mossholder on Unsplash

To use Push notifications you have to:

Check if notifications are supported by the browser

Register a service worker

Ask the user permission

(Optionally) Create a notification subscription

(Optionally) Send the subscription to a Push Server

Display the Push notification

It seems a lot of things, let’s start with the first one.

Check if Notifications are supported by the browser

You want to use notifications only if the browser supports them. Create a function that does this check.

function isPushNotificationSupported() {

return "serviceWorker" in navigator && "PushManager" in window;

}

This function checks if the PushManager and the serviceWorker do exist. It returns true or false;

We need a serviceWorker to handle notifications, so the next thing to do is register one.

Register a service worker

This function registers a file sw.js , which is supposed to stay in the root of our project, so in our react-app in the folder public . Just for now it will be an empty file.

function registerServiceWorker() {

return navigator.serviceWorker.register("/sw.js");

}

The function returns a promise that resolves a serviceWorkerRegistration .

Ask the user permission

Notification can’t be sent without the user’s consent, let’s create a function that asks the permission.

async function askUserPermission() {

return await Notification.requestPermission();

}

This function returns the result of the user consent that can be one of: default , denied and granted . default means the user didn’t give any response.

If the result of this function is granted we can move to the next step.

To push or not to push?

At this point, we are at a crossroads! We have to decide if we want to:

(Just) display notifications

(Send) Push notifications

Photo by Jon Tyson on Unsplash

Push(ed) notifications are the ones you may have seen on Twitter, Facebook, WhatsApp, and similar apps. When your friends write you a message, you get the notification, even if Facebook or WhatsApp is not open.

If you need this kind of notification, continue reading, otherwise, you can skip the next sections and read directly the part about “sending notifications”.

Create the notification subscription

To receive push notifications you need:

a push service : that manages and receives the notification (the browsers offers a push service)

: that manages and receives the notification (the browsers offers a push service) a push subscription : that provides a subscription URL endpoint and allows unsubscription from a push service.

: that provides a subscription URL endpoint and allows unsubscription from a push service. a push server: a server that sends push messages to the push subscription endpoint, which is handled by the browser push service.

To create the push subscription we use the service worker registered earlier.

async function createNotificationSubscription() {

//wait for service worker installation to be ready

const serviceWorker = await navigator.serviceWorker.ready;

// subscribe and return the subscription

return await serviceWorker.pushManager.subscribe({

userVisibleOnly: true,

applicationServerKey: pushServerPublicKey

});

}

The instruction navigator.service.worker.ready waits for the service worker to be ready to be used, because after we register it, could be in other statuses like waiting , installing . If the registration fails, this promise will never be resolved.

We used the PushManager interface to create a subscription and passed two parameters to the method subscribe :

userVisibleOnly : A boolean indicating that the returned push subscription will only be used for messages whose effect is made visible to the user.

: A boolean indicating that the returned push subscription will only be used for messages whose effect is made visible to the user. applicationServerKey : an ECDSA (Elliptic Curve Digital Signature Algorithm) P-256 public key the push server will use to authenticate your application. If specified, all messages from your application server must use the VAPID authentication scheme and include a JWT signed with the corresponding private key. This key IS NOT the same key that you use to encrypt the data.

I’ll show you later how to create a Key pair (private and public) for the push server (the private one) and the application (the public one).

The function returns the PushSubscription , an object that contains the unique endpoint for the push server/service, and some other information. Each browser uses different push services that generate different endpoints. In chrome the endpoint will be something like:

In firefox

If we send a push message to that endpoint, we receive a push notification, so don’t give it to strangers. The endpoint and the information of the push subscriptions need to be sent to Push Server so that it can use it to send messages.

Send the subscription to the Push Server

There is no standard way to send the push subscription to the Push Server.

Twitter uses its API passing a JSON, like this: