Displaying Dynamic Messages Using the Web Notification API

Share this article

Shakespeare holding a caption card in front of a scene from Romeo and Juliet

Displaying Dynamic Messages Using the Web Notification API was peer reviewed by Julian Motz. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!

Shakespeare holding a caption card in front of a scene from Romeo and Juliet

We live in a world where notifications from your favorite websites or applications no longer exist within the confines of your smartphone. It is now commonplace to receive notifications directly from your browser. For example, Facebook sends you notifications if you have a new friend request or someone comments on a story where you are mentioned. Slack, a popular messaging app, sends you notifications when you are mentioned in a conversation.

As a front-end developer, I was curious how I could leverage browser notifications for websites that are not dealing with large streams of information. How can I add browser notifications that are relevant to the visitor based on their interest in my website?

In this article, we will implement a notification system on the Concise CSS website that will alert visitors every time a new version of the framework is released. I’m going to show you how I accomplished this by using localStorage with the browser Notification API.

A browser notification displaying on the concisecss.com website, using the Notification API

Basics of the Notification API

To begin, we need to determine if notifications are supported by the visitor’s web browser. The brunt of the work throughout this tutorial will by done by the notification object.

(function() {
  if ("Notification" in window) {

  }
})();

So far we have only determined if notifications are supported by our visitor’s browser. After we have established that, we need to know if we can display permissions to the visitor.

We store the output of the permission property in a variable. If permission is granted or denied, we return nothing. If we have not requested permission before, we do so with the requestPermission method.

(function() {
  if ("Notification" in window) {
    var permission = Notification.permission;

    if (permission === "denied" || permission === "granted") {
      return;
    }

    Notification.requestPermission();
  }
})();

Popup letting the user to allow or block browser notifications

You should see a notice in your web browser similar to the image above.

Now that we’ve asked for permission, let’s modify our code to display a notification if permission is allowed:

(function() {
  if ("Notification" in window) {
    var permission = Notification.permission;

    if (permission === "denied" || permission === "granted") {
      return;
    }

    Notification
      .requestPermission()
      .then(function() {
        var notification = new Notification("Hello, world!");
      });
  }
})();

JavaScript notification example

Uninspiring, but functional.

Here we use the promise-based syntax of the requestPermission() method to display a notification after permission has been granted. We display the notification using the notification constructor. This constructor takes two parameters, one for a notification title, and one for options. Follow the link to the documentation to find a complete list of options that can be passed.

Storing Framework Versions

Earlier in the article, I mentioned that we would be using localStorage to help us display notifications. Using localStorage is the preferred method of storing persistent client-side information in JavaScript. We will be creating a localStorage key named conciseVersion that will contain the current version of the framework (e.g. 1.0.0). We can then use this key to check for new versions of the framework.

How do we update the value of our conciseVersion key with the latest version of the framework? We need a way of setting the current version whenever someone visits the website. We also need to update that value whenever a new version is released. Every time the conciseVersion value changes, we need to display a notification to the visitor announcing a new version of the framework.

We’re going to solve this problem by adding a hidden element to the page. This element will have a class named js-currentVersion and will only contain the current version of the framework. Because this element exists in the DOM, we can easily interact with it using JavaScript.

This hidden element will be used to store the framework version in our conciseVersion key. We will also use this element to update that key whenever a new version of the framework is released.

<span class="js-currentVersion" aria-hidden="true">3.4.0</span>

We can use a small bit of CSS to hide this element:

[aria-hidden="true"] {
  display: none;
  visibility: hidden;
}

Note: Since this element contains no meaningful content, it is unnecessary for screen readers to access this element. This is why I have set the aria-hidden attribute to true and have used display: none as the means of hiding the element. Please refer to this WebAIM article for more information on hiding content.

Now we can take this element and interact with it in JavaScript. We need to write a function that returns the text inside of the hidden element we just created.

function checkVersion() {
  var latestVersion = document.querySelector(".js-currentVersion").textContent;
}

This function stores the content of the .js-currentVersion element by using the textContent property. Let’s add another variable that will store the content of our conciseVersion localStorage key.

function checkVersion() {
  var latestVersion = document.querySelector(".js-currentVersion").textContent;
  var currentVersion = localStorage.getItem("conciseVersion");
}

Now we have the latest version of our framework in a variable, and we are storing our localStorage key to a variable. It’s time to add the logic that determines if there’s a new version of the framework available.

We first check to see if the conciseVersion key exists. If it does not, we will display a notification to the user, as it’s likely their first time visiting. If the key does exist, we check that its value (stored in the currentVersion variable) is greater than that of the current version (stored in the latestVersion variable). If the latest version of the framework is greater than the version the visitor last saw, we know that a new version has been released.

Note: We’re using the semver-compare library to handle comparing the two version strings.

Knowing this, we display a notification to the visitor and update our conciseVersion key appropriately.

function checkVersion() {
  var latestVersion = document.querySelector(".js-currentVersion").textContent;
  var currentVersion = localStorage.getItem("conciseVersion");

  if (currentVersion === null || semverCompare(currentVersion, latestVersion) === -1) {      
    var notification = new Notification("Hello, world!");

    localStorage.setItem("conciseVersion", latestVersion);
  }
}

To use this function, we’ll need to modify our permission code below.

(function() {
  if ("Notification" in window) {
    var permission = Notification.permission;

    if (permission === "denied") {
      return;
    } else if (permission === "granted") {
      return checkVersion();
    }

    Notification.requestPermission().then(function() {
      checkVersion();
    });
  }
})();

This allows us to display notifications if the user has granted permission previously or if permission has just been granted.

Displaying Notifications

So far, we have only displayed simple notifications to the user that don’t contain much information. Let’s write a function that allows us to create browser notifications on the fly, and control the many different aspects of our notification.

This function has parameters for body text, icon, title as well as an optional link and notification duration. Inside, we create an options object that stores both our notification body text and icon. We also create a new instance of the Notification object, passing in the title of our notification as well as the options object.

Next, we add an onclick handler if we want to link to our notification. We use setTimeout() to close the notification after whatever time has been specified. If no time is specified when calling this function, a default of five seconds is used.

function displayNotification(body, icon, title, link, duration) {
  link = link || null; // Link is optional
  duration = duration || 5000; // Default duration is 5 seconds

  var options = {
    body: body,
    icon: icon
  };

  var n = new Notification(title, options);

  if (link) {
    n.onclick = function () {
      window.open(link);
    };
  }

  setTimeout(n.close.bind(n), duration);
}

Now, let’s modify checkVersion() to display a more informative notification to the user.

function checkVersion() {
  var latestVersion = document.querySelector(".js-currentVersion").textContent;
  var currentVersion = localStorage.getItem("conciseVersion");

  if (currentVersion === null || semverCompare(currentVersion, latestVersion) === -1) {      
    displayNotification(
      `Click to see what's new in v${latestVersion}`,
      "http://concisecss.com/images/logo.png",
      "A new version of Concise is available",
      `https://github.com/ConciseCSS/concise.css/releases/v${latestVersion}`
    );

    localStorage.setItem("conciseVersion", latestVersion);
  }
}

We use our displayNotification function to provide a description, image, title and link for our notification.

Note: we are using ES6 template literals to embed expressions within our text.

Complete Code and Testing

Below you can see the complete code that we’ve written in this tutorial.

See the Pen Implementing Dynamic Browser Notifications by SitePoint (@SitePoint) on CodePen.

Running this code should produce the following notification in your browser.

Final notification example

For testing, you will need to be familiar with notification permissions for your browser. Here are some quick references for managing notifications in Google Chrome, Safari, FireFox, and Microsoft Edge. Additionally, you should be familiar using the developer console to delete and modify localStorage values for ease of testing.

You can test the example by running the script one time and changing the value of the js-currentVersion HTML element so that the script sees the difference. You can also re-run using the same version to confirm that you don’t receive unnecessary notifications.

Taking it Further

That’s all we need to have dynamic browser notifications! If you are looking for more flexibility with your browser notifications, I suggest learning about the Service Worker API. Service workers can be used to react to push notifications that allow the user to become notified, regardless of whether or not they are currently visiting your website, resulting in more timely updates.

If you have any questions, comments or feedback feel free to leave them in the comments below. I would also love to see any examples of how you’ve incorporated JavaScript notifications into your projects.

Frequently Asked Questions (FAQs) about Browser Notification API

What is the Browser Notification API and how does it work?

The Browser Notification API is a feature that allows web applications to display system notifications to users. These notifications are similar to push notifications on mobile devices and can be displayed even when the web page is not in focus. The API works by requesting permission from the user to display notifications. Once permission is granted, the web application can create and display notifications using the Notification object.

How can I request permission to display notifications?

To request permission, you can use the Notification.requestPermission() method. This method will display a dialog box to the user asking for their permission to display notifications. The method returns a Promise that resolves to the permission state, which can be ‘granted’, ‘denied’, or ‘default’.

How can I create and display a notification?

Once permission is granted, you can create and display a notification using the Notification constructor. This constructor takes two arguments: the title of the notification and an options object. The options object can include properties like body (the text of the notification), icon (the icon to display), and tag (an identifier for the notification).

Can I display notifications even when the web page is not in focus?

Yes, the Browser Notification API allows you to display notifications even when the web page is not in focus. This is useful for web applications that need to notify users of important events, even when they are not actively using the application.

How can I handle click events on notifications?

You can handle click events on notifications by adding an event listener to the notification object. The event listener function will be called when the user clicks on the notification.

Can I close a notification programmatically?

Yes, you can close a notification programmatically by calling the close() method on the notification object. This is useful if you want to automatically close the notification after a certain period of time.

Are browser notifications supported in all browsers?

Browser notifications are supported in most modern browsers, including Chrome, Firefox, Safari, and Edge. However, support may vary between different versions of these browsers and some older browsers may not support notifications at all.

Can I customize the appearance of notifications?

The appearance of notifications is largely determined by the operating system and the browser. However, you can customize certain aspects of the notification, such as the title, body text, and icon, using the options object passed to the Notification constructor.

How can I check if the user has granted permission to display notifications?

You can check the current permission state by accessing the Notification.permission property. This property will be ‘granted’ if the user has granted permission, ‘denied’ if they have denied permission, and ‘default’ if they have not yet responded to a permission request.

Can I use the Browser Notification API in a worker script?

Yes, the Browser Notification API can be used in a worker script. This allows you to display notifications from background tasks, even when the main web page is not in focus.

Keenan PayneKeenan Payne
View Author

Hello there! My name is Keenan Payne. I'm a front-end developer based out of San Francisco, CA. I'm currently working for a company called Asana. I also built a front-end framework called concise.css. I'm currently available to hire on a freelance basis.

nilsonjnotification API
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week