DEV Community

Daveyon Mayne 😻
Daveyon Mayne 😻

Posted on

Dreaded Notification prompting can only be done from a user gesture

Notifications

You could remove the heavy lifting from your codebase by harnessing the power browsers already give to you, for free, it's the Notification interface available in all modern browsers.

Except Chrome, when using the api with other browsers, you may receive an error message when you push a notification to your users's browser. This is because most modern browsers implement restrictions on displaying notifications without user gestures as a security and user experience measure. There's a workaround for this and I'll explain through the use of coding examples:

  • Check to see of the user is using a browser other than Chrome
  • Store message(s) in their localStorage
  • Listen for a document click then present message to user.

Simple, huh? Here's the code:

// The notification data
const notificationData = {...}

if(navigator.userAgent.indexOf("Firefox") !== -1 || navigator.userAgent.indexOf("Safari") !== -1 && navigator.userAgent.indexOf("Chrome") === -1) {
  // Store message in localStorage as an array
  let notifications = localStorage.getItem("notifications");
  let notificationArray = [];

  if (notifications) {
    // Parse the stored string back to an array
    notificationArray = JSON.parse(notifications);
  }

  // Append the new notification data to the array
  notificationArray.push(notificationData);

  // Save the updated array as a string in localStorage
  localStorage.setItem("notifications", JSON.stringify(notificationArray));

  // Add an document click event to iterate and show notifications: parse string to array before looping
  document.addEventListener("click", () => {
    const storedNotifications = localStorage.getItem("notifications");
    let storedNotificationArray = [];

    if (storedNotifications) {
      // Parse the stored string back to an array
      storedNotificationArray = JSON.parse(storedNotifications);
    }

    // Loop through the stored notifications and show them
    for (const notification of storedNotificationArray) {
      // Display the notification
      this._displayNotification(notification);
    }

    // Clear the notifications from localStorage
    localStorage.removeItem("notifications");
  });
} else {
  // Show the notification straight away: Chrome and others
  this._displayNotification(notificationData)
}
Enter fullscreen mode Exit fullscreen mode

As the I've explained previously, we check to see if the user is using Firefox and Safari. We then store the message as an array and save to localStorage. Should more messages come in, it get appended to the notification array in the localStorage. We that add an event listener to the document and once clicked, we loop notification array then display to the user. After, the array gets removed from localStorage. _displayNotification would be your function that shows the notification:

_displayNotification = (notification) => {
  // Use the notification data (title, body, image, url) to construct and show the notification
  const n = new Notification(notification.title, { body: notification.body, icon: notification.image, requireInteraction: true });

  n.onclick = (event) => {
    event.preventDefault()

    window.open(notification.url, "_blank")
  }
};
Enter fullscreen mode Exit fullscreen mode

Assuming you already have the user's permission, this should works as is.

What if the user's computer is off or does not have the browser open on your webpage? You've need a different approach such as using a ServiceWorker or your app should know that the user is offline and do something. Notification can get complex but this post is to get around the error message and it works well. I have yet to try other browsers such as Opera. Please let me know what you think in the comments.

Here's a shorter version on my Twitter post πŸ‘‰ https://twitter.com/sylarruby/status/1679598870307696641?s=20

Bye for now ✌🏼

Top comments (0)