Create Custom Inbox UI with React Hooks
Learn how to build a custom notifications UI using React hooks powered by Novu
The @novu/react
package offers an interface that enables you to build a custom notifications UI using React hooks that are powered by real-time data from the Novu services.
These hooks are designed for use in both mobile and web applications, offering a flexible approach to building a custom notifications UI tailored to your application's requirements.
Getting Started
Follow these steps to get started with building your custom inbox UI:
npm install @novu/react
To implement the NovuProvider component, you need to place it in your application's code at the tree level where you want the hooks to be accessible.
import { NovuProvider } from '@novu/react';
function App() {
return (
<NovuProvider
subscriberId="SUBSCRIBER_ID"
applicationIdentifier="APPLICATION_IDENTIFIER"
>
{/* Your app components */}
</NovuProvider>
);
}
You can find the applicationIdentifier
in the Novu Dashboard under the API keys page.
The subscriberId
is the unique identifier of the user in your application, learn more about subscribers here.
For example, you can create a custom popover UI with a bell icon that shows the unread notifications count and a list of notifications.
const YourCustomInbox = () => {
return (
<Popover.Root open={...} onOpenChange={...}>
<Popover.Trigger>
<BellButton />
</Popover.Trigger>
<Popover.Content>
<NotificationsList />
</Popover.Content>
</Popover.Root>
);
};
Bell Button with Unread Count
The BellButton
component fetches the unread notifications count and renders the count value in the indicator:
import { useCounts } from '@novu/react';
function BellButton() {
const { counts } = useCounts({ filters: [{ read: false }] });
const unreadCount = counts?.[0].count ?? 0;
return (
<button>
<BellIcon />
{unreadCount > 0 && <span className="badge">{unreadCount}</span>}
</button>
);
}
Notifications List
The NotificationsList
component retrieves and displays the notifications list with infinite scrolling functionality:
import { useNotifications } from '@novu/react';
function NotificationsList() {
const {
notifications,
error,
isLoading,
isFetching,
refetch,
fetchMore,
hasMore,
} = useNotifications();
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
{notifications.map((notification) => (
<NotificationItem
key={notification.id}
notification={notification}
/>
))}
{hasMore && (
<button onClick={fetchMore}>Load More</button>
)}
</div>
);
}
Notification Item
The NotificationItem
component renders each notification item. When any action is performed on the notification
instance (e.g., "read" button is clicked), the SDK will optimistically update the notification, which will trigger a rerender of the useNotifications
hook.
const NotificationItem = ({ notification }) => {
return (
<div>
{notification.isRead && <span className="dot-indicator" />}
<h3>{notification.subject}</h3>
<p>{notification.body}</p>
<button onClick={() => notification.read()}>Read</button>
<button onClick={() => notification.archive()}>Archive</button>
</div>
);
};
Learn more about the Hook interfaces in the React SDK documentation.