DEV Community

Cover image for 🔔 How i added a web push notification feature in my project
Badejo Emmanuel Adewale
Badejo Emmanuel Adewale

Posted on

🔔 How i added a web push notification feature in my project

Hey everyone! 👋

I am thrilled to announce to you that I have implemented a push notification feature on my ChatX project.
Now you can get real-time updates even when you’re not on the ChatX tab. Anytime someone sends you a message, you’ll get a notification straight to your device.

How it works

1. Service Worker

A Service worker is a JavaScript file that runs in the background of your browser independently from the web page. It allows your app to handle things like push notifications, background syncing, and caching even when the user is not actively on your site.

2. VAPID Keys

These are cryptographic keys that authenticate your server with the browser’s push service. They allow you to send web push notifications securely and directly, without relying on external services like Firebase Cloud Messaging (FCM).

3. Subscription

When a user allows push notifications, the browser creates a subscription object containing an endpoint URL and encryption keys. This subscription is sent to your backend and used to identify and securely send push messages to that user’s device.

Overall Idea

We prompt the user to accept permissions for notification

  1. Service Worker: We register a Service worker. Its job is to listen for push events and trigger notifications sent from the server.

  2. Subscribing to PushManager:
    After permission is granted, we subscribe the user to push notifications through the browser’s PushManager. This returns a subscription object with the endpoint and keys, which we send to our backend to store.

async function subscribeUser() {
  const registration = await navigator.serviceWorker.ready;
  const subscription = await registration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: '<YOUR_PUBLIC_VAPID_KEY>'
  });
  // Send the subscription payload to the server to store 
  await fetch('/api/save-subscription', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(subscription)
  });
}

Enter fullscreen mode Exit fullscreen mode

3 Sending Notifications from the Server:
When there is a new chat message, the server uses the saved subscriptions to send push notifications via the Web Push Protocol using VAPID keys.

const webpush = require('web-push');

webpush.setVapidDetails(
  'mailto:you@example.com',
  process.env.VAPID_PUBLIC_KEY,
  process.env.VAPID_PRIVATE_KEY
);

async function sendNotification(subscription, payload) {
  await webpush.sendNotification(subscription, JSON.stringify(payload));
}
Enter fullscreen mode Exit fullscreen mode

4. Handling Push Events in the Service Worker:

The Service Worker listens for push events and displays notifications to the user.

self.addEventListener('push', event => {
  const data = event.data.json();
  event.waitUntil(
    self.registration.showNotification(data.title, {
      body: data.body,
      icon: '/icon.png',
      data: { url: data.url }
    })
  );
});

self.addEventListener('notificationclick', event => {
  event.notification.close();
  event.waitUntil(clients.openWindow(event.notification.data.url));
});

Enter fullscreen mode Exit fullscreen mode

Next up:

  • Video Chatting functionality using WebRTC
  • Add and remove users from a group

You can check it out live: ChatX

Top comments (8)

Collapse
 
nathan_tarbert profile image
Nathan Tarbert

pretty cool stuff tbh - always makes me curious if adding features like this ever feels like it speeds things up too much for users or if it keeps stuff more connected - you ever second-guess which features actually help the most long-term

Collapse
 
nathan_tarbert profile image
Nathan Tarbert

Real push notifications going in always feels rewarding - I remember the first time I set it up, it made the whole thing feel real.

Collapse
 
jokosenumi_abdulwahab_2ea profile image
Jokosenumi Abdulwahab

Cool

Collapse
 
seydou_doumbouya_1bcbb578 profile image
Seydou Doumbouya

Nice omo mhi

Collapse
 
lovit_js profile image
Lovit

Can’t wait to see the WebRTC video chat feature next — keep up the awesome work!

Collapse
 
professor12 profile image
Badejo Emmanuel Adewale

Thank you @lovit_js

Collapse
 
tunmise_similoluwa_cdfc75 profile image
Tunmise Similoluwa

Sharp

Collapse
 
matthew_olamide_164c65689 profile image
Matthew Olamide

Informative 👍