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
Prop | Type | Default |
---|---|---|
tags? | string[] | - |
read? | boolean | - |
archived? | boolean | - |
limit? | number | - |
onSuccess? | (data: Notification[]) => void | - |
onError? | (error: NovuError) => void | - |
Return Value
Prop | Type | Default |
---|---|---|
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:
Prop | Type | Default |
---|---|---|
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.