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