The Notifications API

· 5 min read · Updated March 7, 2026 · beginner
notifications browser-api push web-api

The Notifications API lets your web application display desktop notifications to users even when they’re not looking at your tab. Whether it’s a new message, a task reminder, or a background process completing, notifications keep users informed in real-time.

In this tutorial, you’ll learn how to request permission, create notifications, handle user interactions, and build a complete notifications system for your web app.

Checking for Notification Support

Before using the Notifications API, check if the browser supports it:

if ('Notification' in window) {
  console.log('Notifications API supported!');
} else {
  console.log('Notifications not supported in this browser');
}

Most modern browsers support the Notifications API, but it’s good practice to check anyway.

Requesting Permission

Before you can display any notification, you must explicitly ask the user for permission. This is a deliberate design choice — browsers require user consent to prevent abuse.

async function requestNotificationPermission() {
  if (!('Notification' in window)) {
    console.log('This browser does not support notifications');
    return;
  }

  if (Notification.permission === 'granted') {
    console.log('Notification permission already granted');
    return;
  }

  if (Notification.permission !== 'denied') {
    const permission = await Notification.requestPermission();
    console.log('Permission status:', permission);
  }
}

// Call it when appropriate (e.g., on a button click)
requestNotificationPermission();

The Notification.requestPermission() method returns a promise that resolves to one of three values:

  • granted — The user has given permission
  • denied — The user has blocked notifications
  • default — The user dismissed the permission prompt

Notice that you can only request permission once. If the user denies it, you cannot ask again — you’d need to guide them to manually enable notifications in browser settings.

Creating Notifications

Once you have permission, creating a notification is straightforward:

function showNotification(title, options = {}) {
  if (Notification.permission !== 'granted') {
    console.log('No permission to show notifications');
    return;
  }

  const notification = new Notification(title, {
    body: options.body || '',
    icon: options.icon || '/notification-icon.png',
    badge: options.badge || '/badge-icon.png',
    tag: options.tag || '',
    requireInteraction: options.requireInteraction || false,
    data: options.data || {}
  });

  // Handle notification click
  notification.onclick = () => {
    window.focus();
    notification.close();
  };

  // Handle notification close
  notification.onclose = () => {
    console.log('Notification closed');
  };

  return notification;
}

// Usage
showNotification('New Message', {
  body: 'You have a new message from Alice',
  icon: '/icons/message.png',
  tag: 'message-123'
});

The Notification constructor accepts a title and an options object with several useful properties:

  • body — The notification text below the title
  • icon — URL of an image to show as the notification icon
  • badge — A small icon shown in the taskbar
  • tag — A string identifier for grouping notifications
  • requireInteraction — Keeps the notification visible until the user interacts with it
  • data — Arbitrary data you want to attach to the notification

Handling Notification Events

Notifications can trigger several events you can listen to:

const notification = new Notification('Task Complete', {
  body: 'Your download has finished'
});

// When user clicks the notification
notification.onclick = (event) => {
  console.log('Notification clicked');
  window.focus();
  // Navigate to the relevant page
  window.location.href = '/downloads';
};

// When notification is closed (by user or auto)
notification.onclose = (event) => {
  console.log('Notification closed after', event.target.timeout, 'ms');
};

// When an error occurs
notification.onerror = (event) => {
  console.error('Notification error:', event);
};

You can also use the onshow event to track when the notification is actually displayed:

notification.onshow = (event) => {
  console.log('Notification shown at', new Date());
  
  // Auto-close after 5 seconds
  setTimeout(() => {
    notification.close();
  }, 5000);
};

Notification Channels (Advanced)

On some browsers (notably Chrome and Edge), you can create notification channels to give users fine-grained control over different types of notifications:

// Note: This works primarily in Chrome/Edge
function createNotificationChannel() {
  if (!('NotificationChannel' in window)) {
    console.log('Notification channels not supported');
    return;
  }

  const channel = new NotificationChannel('messages', {
    description: 'Notifications about new messages',
    importance: NotificationManager.GENERIC,
    lightColor: '#007bff',
    sound: '/sounds/message.mp3'
  });

  channel.addEventListener('notificationclick', (event) => {
    console.log('Message notification clicked');
    event.notification.close();
  });

  return channel;
}

// In practice, you'd register this during service worker setup
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.ready.then((registration) => {
    // Create notification channel via service worker
    console.log('Service Worker ready for notifications');
  });
}

Note: Notification channels require a service worker to work properly — something we’ll cover in a future tutorial about push notifications.

Best Practices

Here are some tips for using notifications effectively:

  1. Ask at the right time — Don’t ask for permission immediately when the page loads. Wait until the user has engaged with your app and understands why notifications would be useful.

  2. Respect the user’s choice — If permission is denied, don’t keep asking. Instead, show a subtle UI element explaining how they can enable notifications in browser settings.

  3. Don’t over-notify — Too many notifications annoy users and lead them to block your site entirely.

  4. Include useful data — Use the data option to attach context to notifications so you can handle clicks intelligently.

  5. Handle permission states — Always check Notification.permission before attempting to create notifications.

A Complete Example

Here’s a practical example combining everything we’ve learned:

class NotificationManager {
  constructor() {
    this.permission = Notification.permission;
  }

  async init() {
    if (this.permission === 'default') {
      await this.requestPermission();
    }
    return this.permission === 'granted';
  }

  async requestPermission() {
    this.permission = await Notification.requestPermission();
    return this.permission;
  }

  notify(title, options = {}) {
    if (this.permission !== 'granted') {
      console.warn('Cannot notify: permission not granted');
      return null;
    }

    const notification = new Notification(title, {
      icon: '/icons/app-icon.png',
      badge: '/icons/badge.png',
      ...options
    });

    return notification;
  }

  notifyNewMessage(sender, preview) {
    return this.notify('New message from ' + sender, {
      body: preview,
      tag: 'messages',
      requireInteraction: true,
      data: { type: 'message', sender }
    });
  }
}

// Usage
const notifications = new NotificationManager();

document.getElementById('enable-btn').addEventListener('click', async () => {
  const granted = await notifications.init();
  if (granted) {
    console.log('Notifications enabled!');
    notifications.notifyNewMessage('Alice', 'Hey, are you free tonight?');
  }
});

Summary

The Notifications API is a powerful way to re-engage users even when they’ve navigated away from your site. Remember these key points:

  • Always request permission before creating notifications
  • Handle the three permission states: granted, denied, and default
  • Use event listeners to respond to user interactions
  • Follow best practices to avoid annoying your users

In the next tutorial, we’ll explore the Clipboard API, another useful browser API for interacting with the user’s system.