useNotifications

Learn how to use the useNotifications hook to fetch and manage notifications in your React application

The useNotifications hook provides a way to fetch and manage notifications in your application. It includes support for pagination, filtering, and real-time updates.

Hook Parameters

PropTypeDefault
tags?
string[]
-
read?
boolean
-
archived?
boolean
-
limit?
number
-
onSuccess?
(data: Notification[]) => void
-
onError?
(error: NovuError) => void
-

Return Value

PropTypeDefault
notifications?
Notification[] | undefined
-
error?
NovuError | undefined
-
isLoading?
boolean
-
isFetching?
boolean
-
refetch?
() => Promise<void>
-
fetchMore?
() => Promise<void>
-
hasMore?
boolean
-
readAll?
() => Promise<{ data?: void; error?: NovuError }>
-
archiveAll?
() => Promise<{ data?: void; error?: NovuError }>
-
archiveAllRead?
() => Promise<{ data?: void; error?: NovuError }>
-

Notification Type

The Notification type from @novu/js includes many properties. Here are the most commonly used ones:

PropTypeDefault
id?
string
-
subject?
string
-
body?
string
-
isRead?
boolean
-
isArchived?
boolean
-
createdAt?
string
-
readAt?
string
-
archivedAt?
string
-
tags?
string[]
-
data?
Record<string, unknown>
-

Example Usage

Here's how to use the useNotifications hook to fetch and display notifications:

import { useNotifications } from "@novu/react";
 
function NotificationsList() {
  const { notifications, hasMore, isLoading, error, fetchMore } =
    useNotifications();
 
  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;
 
  return (
    <div className="space-y-4">
      {notifications?.map((notification) => (
        <div key={notification.id} className="p-4 border rounded-lg">
          <h3 className="font-medium">{notification.subject}</h3>
          <p>{notification.body}</p>
          <div className="flex justify-between text-sm text-gray-500 mt-2">
            <span>{new Date(notification.createdAt).toLocaleString()}</span>
            <span>{notification.isRead ? "Read" : "Unread"}</span>
          </div>
        </div>
      ))}
      {hasMore && (
        <button
          onClick={fetchMore}
          className="w-full p-2 bg-blue-50 text-blue-600 rounded-md"
        >
          Load More
        </button>
      )}
    </div>
  );
}

With Filtering

You can filter notifications by various properties:

import { useNotifications } from "@novu/react";
 
function FilteredNotifications() {
  const { notifications, isLoading } = useNotifications({
    read: false, // Only unread notifications
    tags: ["important", "urgent"], // Only notifications with these tags
    limit: 20, // Fetch 20 notifications per page
  });
 
  if (isLoading) return <div>Loading...</div>;
 
  return (
    <div className="space-y-4">
      {notifications?.map((notification) => (
        <div key={notification.id} className="p-4 border rounded-lg">
          <h3 className="font-medium">{notification.subject}</h3>
          <p>{notification.body}</p>
        </div>
      ))}
    </div>
  );
}

With Infinite Scroll

You can implement infinite scroll using the fetchMore function:

import { useEffect, useRef } from "react";
import { useNotifications } from "@novu/react";
 
function InfiniteNotificationsList() {
  const { notifications, hasMore, isLoading, fetchMore } = useNotifications();
  const observerTarget = useRef(null);
 
  useEffect(() => {
    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0].isIntersecting && hasMore && !isLoading) {
          fetchMore();
        }
      },
      { threshold: 0.5 },
    );
 
    if (observerTarget.current) {
      observer.observe(observerTarget.current);
    }
 
    return () => observer.disconnect();
  }, [hasMore, isLoading, fetchMore]);
 
  if (!notifications) return <div>Loading...</div>;
 
  return (
    <div className="space-y-4">
      {notifications.map((notification) => (
        <div key={notification.id} className="p-4 border rounded-lg">
          <h3 className="font-medium">{notification.subject}</h3>
          <p>{notification.body}</p>
        </div>
      ))}
      {hasMore && <div ref={observerTarget} className="h-10" />}
    </div>
  );
}

Using Notification Actions

The hook provides several actions to manage notifications:

import { useNotifications } from "@novu/react";
 
function NotificationManager() {
  const { notifications, readAll, archiveAll, archiveAllRead, isLoading } =
    useNotifications();
 
  const handleReadAll = async () => {
    const { error } = await readAll();
    if (error) {
      console.error("Failed to mark all as read:", error);
    }
  };
 
  const handleArchiveAll = async () => {
    const { error } = await archiveAll();
    if (error) {
      console.error("Failed to archive all:", error);
    }
  };
 
  const handleArchiveAllRead = async () => {
    const { error } = await archiveAllRead();
    if (error) {
      console.error("Failed to archive read notifications:", error);
    }
  };
 
  return (
    <div>
      <div className="flex gap-2 mb-4">
        <button
          onClick={handleReadAll}
          className="px-3 py-1 bg-blue-500 text-white rounded-md"
          disabled={isLoading}
        >
          Mark All as Read
        </button>
        <button
          onClick={handleArchiveAll}
          className="px-3 py-1 bg-gray-500 text-white rounded-md"
          disabled={isLoading}
        >
          Archive All
        </button>
        <button
          onClick={handleArchiveAllRead}
          className="px-3 py-1 bg-gray-500 text-white rounded-md"
          disabled={isLoading}
        >
          Archive Read
        </button>
      </div>
 
      <div className="space-y-4">
        {notifications?.map((notification) => (
          <div key={notification.id} className="p-4 border rounded-lg">
            <h3 className="font-medium">{notification.subject}</h3>
            <p>{notification.body}</p>
          </div>
        ))}
      </div>
    </div>
  );
}

The notifications list is automatically updated in real-time when new notifications arrive or when notifications are marked as read/unread.

On this page