Going Native with the Web Notifications API

Jack Misteli

In my opinion, notifications are ONE of the main features that separate a website from an app, especially now that Progressive Web Applications (PWAs) are all the rage. So having notifications showing up will make your site feel even more like a native app.

The Notifications API’s interface is through the JavaScript Notification object, which has a lot of properties. Some are visual, others programmatic, some are just metadata and others are even audio-sensorial ones!

The visual properties are as follow:

const notificationsProperties = {
  "title": "Picture Time",
  "body": "Time to look at some random pictures",
  "icon": "https://picsum.photos/200",
  "image": "https://picsum.photos/400",
  // A badge is an image we display
  // when there is not enough space to display the notification
  "badge": "https://picsum.photos/300/200",
  // Direction decides if the notification goes
  // from left to right, right to left or let the browser decide
  "dir": "ltr",
  // As part of the direct user experience we also have 
  // Audio- ....
  "silent": ""
  // ... sensorial
  "vibrate": [200, 100, 200],
}

title, body, icon, image and badge will all look different depending on the operating system you are using. Here is what it looks like on Windows 10:

Notification screenshot on windows


Now let’s take a look at our more programmatic properties (feel free to criticize my classification I’m not super happy with it either 🤓).

{
  //...
  onshow: () => console.log("We are showing a Notification"),
  onerror: () => console.log("There was an error showing a Notification"),
  onclose: () => console.log("Closing the Notification"),
  // Informs the user if a notification replaced a previous one
  renotify: null,
  // If set to true the notification will stick to the screen until the user interacts with it
  requireInteraction: true,
  // We'll get into actions later
  actions: []
}

We’re not going to explore what you can do with the metadata here. But here they are for good measure:

{
  "lang": "",
  "tag": "",
  "timestamp": 1581390179474,
  "data": null
}

Creating a Notification

Now that we sort of know what is in a notification, let’s take a look on how we can create it:

const notification = new Notification('Stop Working', notificationsProperties);

DONE! It is pretty easy. But two important things:

  • The first one is not very important. You might have noticed in our screenshot that the title of the notification was Stop Working. But in our options we set : "title": "Picture Time". That is because the title can only be set in the notification constructor which we set as “Stop Working”.
  • Second important thing. We cannot just force notifications to our users. We need to get their permission first. If you want to learn more about permissions you might want to check out our article about the (Permission API)[/js/permissions-api/].

Here’s a short snippet for dealing with asking for permission:

// Checking if we already have permission to send notifications
const notificationsAllowed = await navigator.permissions.query({name: 'notifications'});

if (notificationsAllowed.state !== 'granted'){
  // Requesting permission
  const permission = await Notification.requestPermission();

  // If the permission is not granted the application won't work
  if (permission !== 'granted') {
    // I am a very sour developer so I replace all of my page with an error message
    // DON'T DO LIKE ME AND BE A FRIENDLY DEV INSTEAD!
    document.body.innerHTML = '<h1> This app can\'t work without notification bye </h1>';
    return;
  }
}
// Then you can continue with your notification driven code

You can also get the notifications status by running:

const notificationsAllowed = Notification.permission;

Actions

Actions are little buttons at the bottom of your notifications. We can define them as followed:

actions: [{
  title: 'Show More',
  action: () => {console.log('code to show more images');}
},{
  title: 'Close',
  action: () => { console.log('Bye bye');}
}]

Notification screenshot on windows with action buttons

However you can’t just add actions to your notification options as we did before. We can only register them in a service worker:

Module: main.js

if('serviceWorker' in navigator) {
  // First we need to register our service worker
  navigator.serviceWorker.register('serviceWorker.js', { scope: './' })
    .then(async () => {
      //... check if notifications are allowed
      // ... define notificationsProperties with actions
      const serviceWorkerRegistration = navigator.serviceWorker.ready
      // This will show the notification with the actions
      serviceWorkerRegistration.showNotification('Stop Working', notificationsProperties);
    });
}

And there you are you have notifications which can also work offline!


Inside of our Service Worker we can register event listeners to see how our users interact with our notifications:

Module: serviceWorker.js

self.addEventListener('notificationclick', (event) => {
	console.log('our user clicked on the notification!')
    // Send user data analytics 🔥 🔥 🔥
}, false);

And there you are! I hope you learned a few tricks and will develop some fancy websites/web apps with a native feel ✨.


Found this helpful?

Support us on Ko-fi
  Tweet It

🕵 Search Results

🔎 Searching...

Sponsored by #native_company# — Learn More
#native_title# #native_desc#
#native_cta#