#14 - Notifying Users Of Updates
Tags: pwa, pwabuilder, webdev, beginners
Published: 2022-02-27 20:19:50

---
title: #14 - Notifying Users Of Updates
published: true
description: Let's continue our #30DaysOfPWA journey by learning how to Notify Users of Updates! https://aka.ms/learn-pwa/30days-blog
tags: pwa, pwabuilder, webdev, beginners
canonical_url: https://microsoft.github.io/win-student-devs/#/30DaysOfPWA/advanced-capabilities/07
series: Learn Progressive Web Apps with 30DaysOfPWA
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pemc6jgzfpmbnx1801lk.jpeg
---


Welcome to Day 14 of #30DaysOfPWA! New to the series? Three things you can do to catch up:

 * Read the kickoff post below for context.
 * Watch the [GitHub Repository](https://github.com/microsoft/win-student-devs) for updates.
 * Bookmark [#30DaysOfPWA Blog](https://aka.ms/learn-pwa/30Days-blog) for resources.

{% link https://dev.to/azure/welcome-to-30daysofpwa-2e54 %}

This is a shortened version of [this canonical post](https://microsoft.github.io/win-student-devs/#/30DaysOfPWA/advanced-capabilities/07) for the #30DaysOfPWA. 

---

## About The Author

Today's post is authored by _Maxim Salnikov_ - a member of the Microsoft Norway Developer Relations team. Follow Maxim at [@webmaxru](https://twitter.com/webmaxru) or here on dev.to.

{% user webmaxru %}

---

Welcome to day **week 2 day 7**  of the [30 Days of PWA](https://aka.ms/learn-pwa/30Days-blog) series! Today's blog post will introduce various ways to keep users notified and re-engaged with your application.

---

## What are notifications?

A notification, in the context of a web application, is a way to re-engage users. Often they are used to alert users to something that's happening in the app’s backend and/or within the app itself. For example:

- A new message in a chat room
- A new version of the app is available
- Your flight is ready for check-in

Various kinds of notifications, based on their severity and urgency, require different kinds of user interaction: from blocking UI until user reaction on some request to no interaction at all, just informing in some prominent or subtle way. As a developer, you choose the exact type of notification based on your application business logic to provide the best user experience.

Notification arrival time is not always predictable (at least from the user's point of view). What if your web application is not open in the user's browser when you sent an update? You have to have some part of the application always "on duty" in the background to listen to the events from your server and potentially show a notification. For sure, only a service worker can handle this scenario.

In this chapter, let's go through some interesting possibilities of keeping users informed, using the power of Progressive Web App APIs.

---

## Application badges

We’ll start with the most subtle way to notify users that "something new" is available - a badge over the app icon. As mobile app users, we are familiar with the concept of badges. They are small graphical elements that are placed over the app icon on the home screen, taskbar, etc. The exact badge appearance depends on the specific platform. Often, this is a circle with contrasting background color containing the number of new items. For example, the number of unread messages in a mailbox.

It's possible to use the same mechanism for web applications, using the [Badging API](https://aka.ms/learn-PWA/30Days-2.7/developer.mozilla.org/docs/Web/API/Badging_API). Of course, since this applies to the application icon, we’re talking specifically about _installed_ web applications (i.e. with offline support via service worker and correct web app manifest) - check ["Make PWA Installable"](../core-concepts/03) and ["Make PWA Work Offline"](../core-concepts/05) sections to learn more about it.

### How to start

To manage a badge over the app icon, there are two methods available: `setAppBadge()` and `clearAppBadge()`. Let's assume we want to inform our user about 3 new messages in the mailbox:

```javascript
// Check if the API is supported
if ('setAppBadge' in navigator) {
    navigator.setAppBadge(2).catch((error) => {
        // Code to handle an error
    });
}
```

To remove a badge:

```javascript
navigator.clearAppBadge()
```

or

```javascript
navigator.setAppBadge(0)
```

This is what an app icon with a badge looks like on the Windows 11 taskbar:

![App badge in Windows taskbar](https://microsoft.github.io/win-student-devs/30DaysOfPWA/advanced-capabilities/_media/badging-task-bar.png)

Here, an icon with a blue badge overlay is a PWA.

You can manage the badge both from your main application and from the service worker. The latter provides a very important use-case of setting the badge when the application tab (or even visible part of the browser) is not open. What are the most relevant events to listen to in your service worker for managing badges? Currently, there are two of them with their pros and cons:

- "push" - when a push notification is received. Pros: we control the exact timing of sending the notification request. Cons: all requirements and limitations of Push API (see details below). Also, it's obligatory to show a browser-native notification on push, so we can’t issue a "silent" badge update.
- "periodicsync" - an event from Periodic Background Sync API we covered in ["Synchronizing app in the background"](../advanced-capabilities/06) section. Pros: there are no other actions or notifications needed, the badge update can happen in the background. Cons: all requirements and limitations of the Periodic Background Sync API. One of them is that there is no way to update the badge at a specific time - it's the browser that decides when to fire this event for a particular installed application, based on the Site Engagement index. And it's going to be, at best, several hours between syncs.

As you see, currently, there is no perfect way to manage the badge from the service worker. The discussion about this topic is ongoing, and there are [some proposals](https://aka.ms/learn-PWA/30Days-2.7/github.com/w3c/badging/blob/main/explainer.md#possible-changes-to-the-push-api) about making Push API work better with badging.

---

## Push notifications on the web

Another well-known mobile platform feature that came to the web — and is relevant to the task of keeping users updated — is push notifications. They are a way to send a packet of data (that might consist of a title, short description, url, image, several other kinds of data) to the user’s device from your backend. Often, push notifications are explained as a possibility for the app owners to re-engage users. Some distinctive features of push notifications are:

- They always use OS- or browser-native UI controls to display the notification. For the web, this is [Notifications API](https://aka.ms/learn-PWA/30Days-2.7/developer.mozilla.org/en-US/docs/Web/API/Notifications_API). It provides the best possible developer and user experience.
- Users explicitly opt-in to receive push notifications and can opt-out at any time. If the app developer doesn't provide the latter option in the UI, users can use platform native tools to block push notifications for the app (on mobile platforms) or for the origin (on the web).
- The user device can receive and show these notifications, regardless of whether the app is open or not. Thus, for the web platform, we listen and react to the corresponding event in a service worker.
- There is always a 3rd party service that handles _subscriptions_ and sends push notifications to the user devices. It's called "Messaging Service" and it's not a part of either the operating system or browser. A Messaging Service is a powerful server and network infrastructure able to deliver messages directly to the devices on a huge scale. As a developer, you can't (and don't need to) choose a specific Messaging Service - you implicitly use it in your code that works with Push API during subscription, unsubscription, sending a notification. And it's free to use.

### How to start

Implementing push notifications on the web includes multiple steps: 

#### Step 1. Getting credentials.

Generate a set of "VAPID keys" to authenticate a user device against the Messaging Service. You need one set of keys (public and private) per app. You can use either [web-push](https://aka.ms/learn-PWA/30Days-2.7/www.npmjs.com/package/web-push) module or one of the many free online services. Using `web-push`:

```shell
npm install web-push -g
web-push generate-vapid-keys --json
```

#### Step 2. Subscribing and saving.

After the user explicitly opts-in to receive push notifications (for example, by clicking a button in the UI), use the `subscribe()` method of the `PushManager` interface (if it's available) of the active service worker registration:

It is a best practice to either hide or disable all related UI controls if there is no Push API support in the browser:

```javascript
if (!('PushManager' in window)) {

    // Code to disable or hide push-related UI controls

    console.log('Push API is not supported');
    return;
}
```

"Subscribe" button handler (for the sake of the example, the code is simplified and doesn't contain error handling):

```javascript
async function subscribeForPush() {
    const registration = await navigator.serviceWorker.ready;

    const pushSubscription = await registration.pushManager.subscribe({
        userVisibleOnly: true, // Should be always true as currently browsers only support explicitly visible notifications
        applicationServerKey: "publicKey from Step 1 converted to Uint8Array"
    });

    // Send push subscription to our server to persist it
    saveSubscription(pushSubscription);
}
```

With that, the subscription process is completed. From here, there are several options to improve the user experience:

- You can request subscription status from the Messaging Service by using `getSubscription()` to set the initial status for subscription UI controls.
- Before subscribing, it's a good idea to [check/request permission for the notification using Notifications API](https://aka.ms/learn-PWA/30Days-2.7/docs.microsoft.com/en-us/microsoft-edge/progressive-web-apps-chromium/how-to/notifications-badges#display-notifications-in-the-action-center). That gives you more control over when the permission prompt is shown. If you skip that step, calling `subscribe()` will prompt the user to grant/deny the notification permission.
- Don't forget to implement unsubscription logic and place corresponding UI controls. It's always better to let users unsubscribe using your code (they can resubscribe again in your app) than to make them block your origin using browser settings (which would require them to unblock your origin in the browser settings again if they want to resubscribe).

You will find an extended code sample that also includes method for converting the `publicKey` to Uint8Array [here](https://aka.ms/learn-PWA/30Days-2.7/docs.microsoft.com/en-us/microsoft-edge/progressive-web-apps-chromium/how-to/notifications-badges#step-2---subscribe-to-push-notifications).


#### Step 3. Sending a notification.

In your backend, iterate through the push subscription objects you received and saved in Step 2 to send a special HTTPS request to the Messaging Service for each of them. Good to remember: push notifications on the web are not limited to broadcast messages. You can send a specific notification to a specific user device if together with the push subscription object you pass some user-identifying data (like your internal user ID) to the backend, so you can iterate over only specific subscriptions.

To build a request that follows Web Push protocol, you use:

- `endpoint` field from the subscription object that is actually a URL of the Messaging Service with a unique device token
- VAPID keys you generated in Step 1
- The payload you want to send to the user device for this particular notification. Often, you `JSON.stringify()` the object following [Notification](https://aka.ms/learn-PWA/30Days-2.7/developer.mozilla.org/en-US/docs/Web/API/Notification/Notification) specification.

The simpler way to send a notification from your NodeJS backend is using `sendNotification()` method from the [web-push](https://aka.ms/learn-PWA/30Days-2.7/www.npmjs.com/package/web-push) module. There are similar libraries for [other platforms](https://aka.ms/learn-PWA/30Days-2.7/github.com/web-push-libs) available.

The Messaging Service receives your request and sends a push notification to the user.


#### Step 4. Receiving and displaying.

To receive a notification, a service worker on the user device listens for the `push` event and handles it:

```javascript
self.addEventListener('push', (event) => {
    const notificationData = JSON.parse(event.data.text());

    event.waitUntil(
        self.registration.showNotification(notificationData.title, {
            body: notificationData.message,
            icon: notificationData.icon
        });
    );
});
```

To react to the user actions, you can also provide handlers for the `notificationclick` and `notificationclose` events in the service worker.

Because of the web specifics, push notifications there have some extra interesting points:

- Showing notification with data sent as a payload from your server (proxied by the Messaging Service) is only one possible scenario. Before displaying the notification, you can, for example, do another API call to request additional data. Of course, you have to consider limited service worker execution time. So all that happens in your code before calling `showNotification()` should not be too long.
- In a service worker, on receiving a `push` event, you MUST use `showNotification()` to show a native notification to the user (with only [one exception](https://aka.ms/learn-PWA/30Days-2.7/developers.google.com/web/fundamentals/push-notifications/common-notification-patterns#the_exception_to_the_rule)). If this method is not called or called incorrectly, the notification will still be shown informing the user about "something happened with your app in the background" (the exact text is decided by the browser). This is done to prevent malicious apps from "waking up" service workers by a signal from the backend without letting the user know about it.
- On Windows, push notifications are integrated into the Action Center.

![A push notification in the Windows Action Center](https://microsoft.github.io/win-student-devs/30DaysOfPWA/advanced-capabilities/_media/notifications-action-center.png)

On other operating systems, they might be also integrated into centralized notification UI or look like standalone browser-native dialogs.

There is a [web-push demo](https://aka.ms/learn-PWA/30Days-2.7/webpushdemo.azurewebsites.net) with the [source code available](https://aka.ms/learn-PWA/30Days-2.7/github.com/MicrosoftEdge/pushnotifications-demo) that you can use to explore the notification functionality.

---

## Learn more about notifying your users of updates

- [Re-engage users with badges, notifications, and push messages](https://aka.ms/learn-PWA/30Days-2.7/docs.microsoft.com/en-us/microsoft-edge/progressive-web-apps-chromium/how-to/notifications-badges) article on Microsoft Docs
- Specifications for [Badging API](https://aka.ms/learn-PWA/30Days-2.7/w3c.github.io/badging) and [Push API](https://aka.ms/learn-PWA/30Days-2.7/www.w3.org/TR/push-api)
- API documentation for [Badging API](https://aka.ms/learn-PWA/30Days-2.7/developer.mozilla.org/docs/Web/API/Badging_API) and [Push API](https://aka.ms/learn-PWA/30Days-2.7/developer.mozilla.org/en-US/docs/Web/API/Push_API) on Mozilla Developer Network.
- [Web Push Book](https://aka.ms/learn-PWA/30Days-2.7/web-push-book.gauntface.com)
- [Voluntary Application Server Identification (VAPID) for Web Push](https://aka.ms/learn-PWA/30Days-2.7/datatracker.ietf.org/doc/html/draft-ietf-webpush-vapid-00)
- [Web Push protocol](https://aka.ms/learn-PWA/30Days-2.7/datatracker.ietf.org/doc/html/draft-ietf-webpush-protocol)

---

## Next Week: Developer Tools!

We are about to cross the half-way mark of our #30DaysOfPWA journey. By now, you should have a solid foundation of core concepts, and have hands-on experience working with advanced capabilities. 

Here's a sneak peek at what's in store for Week 3 - get ready to dive into developer tools to jumpstart your PWA, debug it, audit it for performance & accessibility, integrate testing and automation workflows, and package it to publish in app stores.

![Visual Guide to Week 3 Roadmap](https://microsoft.github.io/win-student-devs/30DaysOfPWA/dev-tools/_media/week3-roadmap.png)

---

Want to read more content from Microsoft technologists? Don't forget to follow Azure right here on dev.to:

{% org azure %}

---