Skip to main content

useNotifications

Location: src/hooks/useNotifications.js

Overview​

Provides comprehensive notification management for the current user. Fetches notifications from the notifications table, subscribes to real-time updates (INSERT and UPDATE), and supports marking individual, multiple, or all notifications as read, as well as deleting notifications. All mutations use optimistic updates with rollback on error.

Signature​

function useNotifications(userId: string): {
// State
notifications: Notification[],
unreadCount: number,
isLoading: boolean,
error: string | null,
// Actions
markAsRead: (notificationId: string) => Promise<void>,
markMultipleAsRead: (notificationIds: string[]) => Promise<void>,
markAllAsRead: () => Promise<void>,
deleteNotification: (notificationId: string) => Promise<void>,
refresh: () => void,
fetchNotifications: (limit?: number) => Promise<void>,
fetchUnreadCount: () => Promise<void>,
clearError: () => void
}

Parameters​

ParameterTypeRequiredDescription
userIdstringYesThe current user's ID

Return Value​

PropertyTypeDescription
notificationsNotification[]Array of notification objects, ordered by created_at descending
unreadCountnumberNumber of unread notifications
isLoadingbooleanWhether notifications are being fetched
errorstring | nullError message if fetching or mutations failed
markAsRead(notificationId) => Promise<void>Mark a single notification as read (optimistic update)
markMultipleAsRead(notificationIds) => Promise<void>Mark multiple notifications as read via mark_notifications_read RPC
markAllAsRead() => Promise<void>Mark all notifications as read via mark_all_notifications_read RPC
deleteNotification(notificationId) => Promise<void>Delete a notification (optimistic update with rollback)
refresh() => voidRe-fetch all notifications
fetchNotifications(limit?) => Promise<void>Fetch notifications with an optional limit (default 50)
fetchUnreadCount() => Promise<void>Fetch only the unread count via get_unread_notification_count RPC
clearError() => voidClear the error state

Usage​

import { useNotifications } from '../hooks/useNotifications';

function NotificationsPanel({ userId }) {
const {
notifications,
unreadCount,
isLoading,
markAsRead,
markAllAsRead,
deleteNotification
} = useNotifications(userId);

if (isLoading) return <Skeleton />;

return (
<div>
<header>
<h2>Notifications ({unreadCount} unread)</h2>
<button onClick={markAllAsRead}>Mark all read</button>
</header>
{notifications.map(n => (
<NotificationItem
key={n.id}
notification={n}
onRead={() => markAsRead(n.id)}
onDelete={() => deleteNotification(n.id)}
/>
))}
</div>
);
}

Notes​

  • Real-time subscriptions listen for both INSERT (new notifications) and UPDATE (read status changes) events.
  • All write operations use optimistic updates and revert on error.
  • The Supabase channel is cleaned up on unmount to prevent memory leaks.

Last updated: 2026-02-07