pwshub.com

How to display notification badges on PWAs using the Badging API

Ding! You got a notification, but does it cause a little bump of dopamine or a slow drag of cortisol?

The difference between “Ooo, a new message!” and, “Oh, spare me!” are unique to your own situation, but both are visually dependent on badges.

Specifically, the Badging API allows progressive web applications (PWAs) to display notification badges on their icons like native applications.

For example, here’s a familiar visual with counters at the top-right corner of each app:

Example of notification badges displayed on App Store, WhatsApp, and Slack icons using the Badging API for PWAs.

The Badging API allows progressive web apps to display these icon notification badges.

I’m going to show you how the Badging API works and its current state of compatibility. Then I’ll you walk through a brief tutorial to see the API in action.

Finally, using the Badging API in the main thread of a web application is straightforward, so I’ll go over how to use it in the background of a web application through worker threads.

I’m crossing my fingers that you’ll experience a rush of dopamine by the time you’re done reading and implementing what we’ve learned. 🤞

Methods from the Badging API

The navigator object provides two methods for the Badging API:

  • navigator.setAppBadge() for displaying the notification badge
  • navigator.clearAppBadge() for removing the badge

The navigator.setAppBadge() method takes in a number input greater than 0 to display on the badge, like this example to display the number 22 in a notification badge:

navigator.setAppBadge(22)

Passing 0 removes the notification badge the same way calling navigator.clearAppBadge() without any argument clears the badge:

navigator.setAppBadge(0)
navigator.clearAppBadge()
// They both do the same thing

Compatibility note

As of writing this guide the Badging API isn’t widely supported:

Browser compatibility table showing support for the Badging API's setAppBadge method across different browsers and devices.

How the Badging API is implemented across supported browsers varies. The API may not look or function the same way across the browsers that support it.

Lastly, the Badging API is only available to web applications that are delivered using the HTTPS protocol and localhost on supported browsers. You most likely won’t have to worry, but if you have any issues with it and you’re using a supported browser, this could be helpful to know.

Building the reminder application

To better understand the Badging API, we’ll look at a step-by-step process of building a simple reminder web application that would use it.

Setting up the project structure

Before building the project, let’s start with a basic structure:

reminder-app/
|-- index.html
|-- style.css
|-- app.js
|-- manifest.json

Creating the HTML and style

We’ll use a simple HTML and style for our app. Here it is for index.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Reminder PWA</title>
        <link rel="manifest" href="manifest.json">
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <h1>Reminder PWA</h1>
        <input type="text" id="reminder-input" placeholder="Enter a reminder">
        <button onclick="addReminder()">Add Reminder</button>
        <button onclick="clearReminders()">Clear Reminders</button>
        <ul id="reminder-list"></ul>
        <script src="app.js"></script>
    </body>
</html>

And here is it is for style.css:

body {
    font-family: Arial, sans-serif;
}

This will render something like this:

Reminder PWA interface showing an input field for reminders with buttons to add or clear reminders, and a list of reminders.

Creating a web manifest with manifest.json

To make our web app progressive, you need a manifest file. The manifest file contains every information your web app needs to be installed like a native app:

{
    "short_name": "Reminder",
    "name": "Reminder Web Application",
    "icons": [
        {
            "src": "icon.png",
            "sizes": "192x192",
            "type": "image/png"
        }
    ],
    "start_url": ".",
    "display": "standalone",
    "theme_color": "#000000",
    "background_color": "#ffffff"
}

The sixth line of the manifest.json file points to an icon.png file to use for the icon of the web app when you install it. You may need to get an image file, rename it to icon.png, and move it to the root directory of this project.

The JavaScript logic
In this section, we’ll write the logic for app.js:

<let count = 0;
const input = document.getElementById("reminder-input");
const list = document.getElementById("reminder-list");
function addReminder() {
    const item = document.createElement("li");
    item.textContent = input.value;
    list.appendChild(item);
    count++;
    updateBadge();
    input.value = ""; // Clear input after adding
}
function clearReminders() {
    list.replaceChildren();
    count = 0;
    updateBadge();
}
function updateBadge() {
    if ("setAppBadge" in navigator) {
        navigator.setAppBadge(count).catch((error) => {
            console.error("Badging failed:", error);
        });
    } else {
        console.error("Badging API not available");
    }
}

The updateBadge() function uses the Badging API to set and clear the notification badge.

Using the Badging API in worker threads

Sometimes, you may want to update the application badge in the background. To do that you’ll need to use service workers.

Service workers are a type of worker threads that act as a proxy between a web application and a server. Service workers allow web applications to cache files that are important to the web application to allow offline usage, and to make use of background sync functionality.

Because they’re worker threads, they can also run in a background thread separate from the main thread of your web app.

Before you use service workers in your web application, you need to first register it. To register a service worker, add this line to the app.js file:

<window.addEventListener(‘load’, () => {
    if ('serviceWorker' in navigator) {
        navigator.serviceWorker.register('sw.js');
    }
});

This example registers an sw.js file as a service worker. Now, we create the sw.js file and write the service worker code into it.


More great articles from LogRocket:

  • Don't miss a moment with The Replay, a curated newsletter from LogRocket
  • Learn how LogRocket's Galileo cuts through the noise to proactively resolve issues in your app
  • Use React's useEffect to optimize your application's performance
  • Switch between multiple versions of Node
  • Discover how to use the React children prop with TypeScript
  • Explore creating a custom mouse cursor with CSS
  • Advisory boards aren’t just for executives. Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.

Let’s go over some basics. You can access the context of the service worker with self. You can also attach event listeners to the contexts with the self.addEventListener() method.

For example, if we want to perform any action when the service worker is installed, we can attach an event listener to the install event:

<self.addEventListener("install", (event) => {
    console.log("Service Worker installing.");
});

Similarly, we can do the same for fetching items from the server with the fetch event:

<self.addEventListener("fetch", (event) => {
    console.log("Fetching:", event.request.url);
});

The Badging API supports push notification and background sync events. These are events that can run in the background. This is sync which gets triggered on background sync events:

<self.addEventListener("sync", (event) => {
    if ("setAppBadge" in navigator) {
        navigator.setAppBadge(count).catch((err) => {
            console.error("Badging failed:", err);
        });
    } else {
        console.error("Badging not supported");
    }
});

This is push which gets triggered when a push notification is passed:

<self.addEventListener("push", (event) => {
    if ("setAppBadge" in navigator) {
        const count = event.data.json().badgeCount;
        navigator.setAppBadge(count).catch((err) => {
            console.error("Badging failed:", err);
        });
    } else {
        console.error("Badging not supported");
    }
});

Finally, I ran a simple experiment to see if you can use the Badging API outside the push and sync event handlers. And it turns out that you can! This is the code I added to the sw.js file:

<let count = 0;
setInterval(() => {
    count++;
    if ("setAppBadge" in navigator) {
        navigator.setAppBadge(count).catch((error) => {
            console.error("Badging failed:", error);
        });
    } else {
        console.log("Badging API not available");
    }
}, 1000);

So far it works well on Safari and Chrome on macOS. You can close the web app window, and the badge keeps on going in the background until you quit the application, which is how most applications work.

Conclusion

The Badging API is a powerful tool that lets progressive web apps subtly notify its users that the internal state of the application is changed. The Badging API also makes progressive web apps feel more like native apps.

I hope this guide helps you understand the Badging API. If I’ve forgotten anything, let me know in the comments, and I might even get a notification. 😉

Hey there, want to help make our blog better?

Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.

Sign up now

Source: blog.logrocket.com

Related stories
1 week ago - An employee recognition platform is a tool to create a workplace where employee’s efforts are seen and celebrated. These platforms turn the everyday moments of appreciation into a structured, visible, and impactful part of company...
1 week ago - An employee experience platform (EEP) is designed to enhance workplace satisfaction and productivity by streamlining HR processes. It is a central location for employee resources, collaboration, and communication. Employee Experience...
1 month ago - Collaboration and communication software are designed to facilitate effective communication between teams regardless of location while managing projects or tasks. As the world becomes more digital and workplaces become more global, the...
1 month ago - The challenge of understanding complex systems Imagine a scenario where a project is so large and its features so complex that tracking and understanding the …
1 week ago - Building projects is a great way to practice and improve your web development skills. And that's what we'll do in this in-depth tutorial: build a practical project using HTML, CSS, and JavaScript. If you often find yourself wondering...
Other stories
1 hour ago - Ubuntu 24.10 ‘Oracular Oriole’ is released on October 13th, and as you’d expect from a new version of Ubuntu, it’s packed with new features. As a short-term release, Ubuntu 24.10 gets 9 months of ongoing updates, security patches, and...
3 hours ago - Did you know that CSS can play a significant role in web accessibility? While CSS primarily handles the visual presentation of a webpage, when you use it properly it can enhance the user’s experience and improve accessibility. In this...
4 hours ago - Design thinking workshops are your key to turning big problems into clear solutions. In this blog, I share how to run them efficiently and keep your team aligned. The post How to run a design thinking workshop appeared first on LogRocket...
4 hours ago - New memory-optimized X8g instances offer up to 3 TiB DDR5 memory, 192 vCPUs, and 50 Gbps network bandwidth, designed for memory-intensive workloads like databases, analytics, and caching with unparalleled price/performance and efficiency.
4 hours ago - Gain indispensable data engineering expertise through a hands-on specialization by DeepLearning.AI and AWS. This professional certificate covers ingestion, storage, querying, modeling, and more.