title | sidebarTitle | description |
---|---|---|
React Get Started |
Get Started |
Learn how to add novu powered In-App notification center to your React app |
Novu provides the @novu/notification-center
a React library that helps to add a fully functioning notification center to your web application in minutes. Let's do a quick recap on how you can easily use it in your application.
- Install
@novu/notification-center
npm package in your react app
npm install @novu/notification-center
- Add the below code in the app.tsx file
import {
NovuProvider,
PopoverNotificationCenter,
NotificationBell,
IMessage,
} from "@novu/notification-center";
function Novu() {
return (
<NovuProvider
subscriberId={"SUBSCRIBER_ID"}
applicationIdentifier={"APPLICATION_IDENTIFIER"}
>
<PopoverNotificationCenter colorScheme="dark">
{({ unseenCount }) => <NotificationBell unseenCount={unseenCount} />}
</PopoverNotificationCenter>
</NovuProvider>
);
}
Go to this react app browser tab, there will be a bell icon. On clicking that bell icon, you will see a notification component popover
By default, Novu's hosted services of API and socket are used. If you want, you can override them and configure your own.
import {
NovuProvider,
PopoverNotificationCenter,
NotificationBell,
} from "@novu/notification-center";
function Novu() {
return (
<NovuProvider
backendUrl={"YOUR_BACKEND_URL"}
socketUrl={"YOUR_SOCKET_URL"}
subscriberId={"SUBSCRIBER_ID"}
applicationIdentifier={"APPLICATION_IDENTIFIER"}
>
<PopoverNotificationCenter colorScheme="dark">
{({ unseenCount }) => <NotificationBell unseenCount={unseenCount} />}
</PopoverNotificationCenter>
</NovuProvider>
);
}
If you don't want to show the bell icon, you can directly render the notification center component without passing the bell, use <NotificationCenter>
component in place of <PopoverNotificationCenter>
import {
NovuProvider,
NotificationCenter,
} from "@novu/notification-center";
<NovuProvider
subscriberId={"SUBSCRIBER_ID"}
applicationIdentifier={"APPLICATION_IDENTIFIER"}
>
<NotificationCenter colorScheme="dark" />
</NovuProvider>
When Novu's user adds the notification center to their application they are required to pass a subscriberId
which identifies the user's end-customer, and the application Identifier which is acted as a public key to communicate with the notification feed API.
A malicious actor can access the user feed by accessing the API and passing another subscriberId
using the public application identifier.
HMAC encryption will make sure that a subscriberId
is encrypted using the secret API key, and those will prevent malicious actors from impersonating users.
In order to enable Hash-Based Message Authentication Codes, you need to visit the admin panel In-App settings page and enable HMAC encryption for your environment.
- Next step would be to generate an HMAC encrypted subscriberId on your backend:
import { createHmac } from "crypto";
const hmacHash = createHmac("sha256", process.env.NOVU_API_KEY)
.update(subscriberId)
.digest("hex");
- Then pass the created HMAC to your client side application forward it to the component:
<NovuProvider
subscriberId={"SUBSCRIBER_ID_PLAIN_VALUE"}
subscriberHash={"SUBSCRIBER_ID_HASH_VALUE"}
applicationIdentifier={"APPLICATION_IDENTIFIER"}
>
<NotificationCenter colorScheme="dark" />
</NovuProvider>
If HMAC encryption is active in In-App provider settings and subscriberHash
along with subscriberId
is not provided, then notification center will not load
This function is invoked when the user clicks anywhere on the notification except for CTA actions.
import {
NovuProvider,
PopoverNotificationCenter,
NotificationBell,
IMessage,
} from "@novu/notification-center";
function Novu() {
function handleOnNotificationClick(message: IMessage) {
// your logic to handle the notification click
if (message?.cta?.data?.url) {
window.location.href = message.cta.data.url;
}
}
return (
<NovuProvider
subscriberId={"SUBSCRIBER_ID"}
applicationIdentifier={"APPLICATION_IDENTIFIER"}
>
<PopoverNotificationCenter
colorScheme="dark"
onNotificationClick={handleOnNotificationClick}
>
{({ unseenCount }) => <NotificationBell unseenCount={unseenCount} />}
</PopoverNotificationCenter>
</NovuProvider>
);
}
This function is invoked when the user clicks on the action CTA buttons of the notification
import {
NovuProvider,
PopoverNotificationCenter,
IMessage,
MessageActionStatusEnum,
useUpdateAction,
ButtonTypeEnum,
NotificationBell,
} from "@novu/notification-center";
export default function Novu() {
const CustomNotificationCenter = () => {
const { updateAction } = useUpdateAction();
const handleOnActionClick = async (
templateIdentifier: string,
btnType: ButtonTypeEnum,
notification: IMessage
) => {
if (templateIdentifier === "friend-request") {
if (btnType === "primary") {
/** Call your API to accept the friend request here **/
/** And then update Novu that this action has been taken, so the user won't see the button again **/
updateAction({
messageId: notification._id,
actionButtonType: btnType,
status: MessageActionStatusEnum.DONE,
});
}
}
};
return (
<PopoverNotificationCenter
colorScheme={"dark"}
onActionClick={handleOnActionClick}
>
{({ unseenCount }) => <NotificationBell unseenCount={unseenCount} />}
</PopoverNotificationCenter>
);
};
return (
<NovuProvider
subscriberId={"SUBSCRIBER_ID"}
applicationIdentifier={"APPLICATION_IDENTIFIER"}
>
<CustomNotificationCenter />
</NovuProvider>
);
}
CTA buttons text and redirect url field supports dynamic variables
Novu provides a real-time socket API for you to consume and get updates about new notifications added to the user's feed. To use the socket connection you can use the useSocket
hook provided by the @novu/notification-center
library. Let's see an example of that:
import { NovuProvider, useSocket } from "@novu/notification-center";
function Novu() {
return (
<NovuProvider
subscriberId={"SUBSCRIBER_ID"}
applicationIdentifier={"APPLICATION_IDENTIFIER"}
>
<CustomNotificationCenter />
</NovuProvider>
);
}
function CustomNotificationCenter() {
const { socket } = useSocket();
useEffect(() => {
if (socket) {
socket.on("notification_received", (data) => {
console.log(data);
});
}
return () => {
if (socket) {
socket.off("notification_received");
}
};
}, [socket]);
return <></>;
}
There are three sockets events available:
unseen_count_changed
unread_count_changed
notification_received
Novu does not have a native taost component. However, if your project is using any UI library like chakra, material-ui, mantine then toast component (snackbar in case of material-ui) of these libraries can be used with useSocket
hook. Add the toast opening code in socket.on
callback.
socket.on("notification_received", (data) => {
console.log(data);
// set received notification content as toast content
setToastContent(data.content)
// open the toast
openToast(true)
});
Possible reasons for the notification center not loading properly:
- Invalid subscriberId
- Invalid applicationIdentifier
- Invalid subscriberHash (in case of active HMAC encryption)
- Invalid backendUrl (in case of self-hosted)
- Invalid socketUrl (in case of self-hosted)
The notification center should be wrapped in <NovuProvider>
The redirect URL is for the entire notification item, When the user clicks the notification, the user will be routed to that url. CTA are two call-to-action buttons. onNotificationClick
function prop is used for redirecting url and the onActionClick
function prop is used for CTA.
Bell icon and notification center in Novu dashboard is only for receiving system related notifications like user you invited has joined, password reset request sent. It can not to used to test notification center. Consider using our codesandbox example instead.
Our notification center is configures for all hosts. Please disable root level `withCredentials` config in axios or fetch http requests.