title | sidebarTitle | description |
---|---|---|
Customizing Notification Center |
Customization |
Learn how to customize the pre built notification center component partially or building your own notification center component from scratch using Novu provided hooks |
<PopoverNotificationCenter>
is a pre built notification center component that can be used to show notifications in your application. It is a popover component that can be placed anywhere in your application. A bell will appear on the page. On click of that bell, a popover will appear. Checkout all customizations and available props. If you are looking for a component without popover use regular <NotificationCenter>
component. Checkout props of this component. Few selected customization options are explained below:-
It is common that you might have a special set of icons you use within your application and you will want to replace the default: NotificationBell
coming from our library.
For this you can easily switch the NotificationBell
with your own bell. Just make sure you pass the unseenCount
param inside and use it accordingly.
<PopoverNotificationCenter colorScheme="dark">
{({ unseenCount }) => (
<CustomBell
unseenCount={unseenCount}
colorScheme="dark"
unseenBadgeBackgroundColor="#FFFFFF"
unseenBadgeColor="#FF0000"
/>
)}
</PopoverNotificationCenter>
To support dark mode in your application the notification center component can receive a colorScheme
prop that can receive either dark
or light
mode.
<PopoverNotificationCenter colorScheme={"dark" || "light"}>
{({ unseenCount }) => <NotificationBell unseenCount={unseenCount} />}
</PopoverNotificationCenter>
Use position
and offset
prop to position the popover relative to the Bell icon
<PopoverNotificationCenter position="left-start" offset={20}>
{({ unseenCount }) => <NotificationBell unseenCount={unseenCount} />}
</PopoverNotificationCenter>
Use header
, footer
and emptyState
prop to customize the header, footer and empty state of notification center.
const Header = () => {
return <span> My custom header </span>;
};
const Footer = () => {
return <span> My custom footer </span>;
};
const EmptyState = () => {
return <span> My custom empty state </span>;
};
<PopoverNotificationCenter
colorScheme="dark"
header={() => <Header />}
footer={() => <Footer />}
emptyState={<EmptyState />}
>
{({ unseenCount }) => <NotificationBell unseenCount={unseenCount} />}
</PopoverNotificationCenter>;
Use the listItem prop to show custom notification items.
<PopoverNotificationCenter
colorScheme={colorScheme}
onNotificationClick={handlerOnNotificationClick}
onActionClick={handlerOnActionClick}
listItem={(
notification,
handleActionButtonClick,
handleNotificationClick
) => {
return (
<a
href="/"
onClick={(e) => {
e.preventDefault();
handleNotificationClick();
}}
>
{notification.content}
</a>
);
}}
>
{({ unseenCount }) => {
return <NotificationBell unseenCount={unseenCount} />;
}}
</PopoverNotificationCenter>
If you want to use a language other than english for the UI, the NovuProvider
component can accept an optional i18n
prop.
<NovuProvider
subscriberId={"USER_ID"}
applicationIdentifier={"APPLICATION_IDENTIFIER"}
i18n="en"
>
<PopoverNotificationCenter colorScheme="dark">
{({ unseenCount }) => <NotificationBell unseenCount={unseenCount} />}
</PopoverNotificationCenter>
</NovuProvider>
The i18n
prop can accept 2 different types of values
- 2 letter language string
i18n = "en";
af
(Afrikaans)am
(Amharic)ar
(Arabic)as
(Assamese)az
(Azerbaijani)ba
(Bashkir)be
(Belarusian)bg
(Bulgarian)bh
(Bihari)bn
(Bengali)bs
(Bosnian)ca
(Catalan)cs
(Czech)da
(Danish)de
(German)el
(Greek)en
(English)es
(Spanish)eu
(Basque)fa
(Farsi)fi
(Finnish)fr
(French)ga
(Irish)gl
(Galician)gu
(Gujarati)he
(Hebrew)hi
(Hindi)hr
(Croatian)hu
(Hungarian)hy
(Armenian)id
(Indonesian)ig
(Igbo)it
(Italian)ja
(Japanese)ka
(Kannada)kk
(Kazakh)km
(Khmer)ko
(Korean)ku
(Kurdish)lo
(Lao)lt
(Lithuanian)lv
(Latvian)ml
(Malayalam)mr
(Marathi)ms
(Malay)nb
(Norwegian)ne
(Nepali)nl
(Dutch)or
(Odia)pa
(Punjabi)pl
(Polish)pt
(Portuguese)ro
(Romanian)ru
(Russian)sa
(Sanskrit)sd
(Sindhi)si
(Sinhala)sm
(Samoan)sq
(Albanian)sv
(Swedish)sq
(Albanian)ta
(Tamil)te
(Telugu)th
(Thai)tl
(Tagalog)tr
(Turkish)uk
(Ukrainian)ur
(Urdu)uz
(Uzbek)vi
(Vietnamese)zh
(Chinese)zu
(Zulu)
i18n={{
// Make sure that the following is a proper language code,
// since this is used by Intl.RelativeTimeFormat in order to calculate the relative time for each notification
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat
lang: "de",
translations: {
poweredBy: "von",
markAllAsRead: "Alles als gelesen markieren",
notifications: "Benachrichtigungen",
settings: "Einstellungen",
},
}}
Novu uses en
as the default value for i18n
styles
prop can be used to cutomise styling of each component of notification center. Read more about styles prop
export const styles = {
bellButton: {
root: {
marginTop: "20px",
svg: {
color: "#AFE1AF",
fill: "white",
minWidth: "20px",
minHeight: "20px"
}
},
dot: {
rect: {
fill: "white",
strokeWidth: "0",
width: "3px",
height: "3px",
x: 10,
y: 2
}
}
}
}
export const styles = { bellButton: { root: { marginTop: "20px", svg: { color: secondaryColor, fill: primaryColor, minWidth: "20px", minHeight: "20px" } }, dot: { rect: { fill: primaryColor, strokeWidth: "0", width: "3px", height: "3px", x: 10, y: 2 } } }, unseenBadge: { root: { color: primaryTextColor, background: secondaryColor } }, popover: { root: { zIndex: -99 }, arrow: { backgroundColor: primaryColor, borderLeftColor: secondaryColor, borderTopColor: secondaryColor }, dropdown: { border: dropdownBorderStyle, borderRadius: "10px", marginTop: "25px", maxWidth: ncWidth } }, header: { root: { backgroundColor: primaryColor, "&:hover": { backgroundColor: primaryColor }, cursor: "pointer", color: primaryTextColor }, cog: { opacity: 1 }, markAsRead: { color: primaryTextColor, fontSize: "14px" }, title: { color: primaryTextColor }, backButton: { color: primaryTextColor } }, layout: { root: { background: primaryColor, maxWidth: ncWidth } }, loader: { root: { stroke: primaryTextColor } }, accordion: { item: { backgroundColor: secondaryColor, ":hover": { backgroundColor: secondaryColor } }, content: { backgroundColor: secondaryColor, borderBottomLeftRadius: "7px", borderBottomRightRadius: "7px" }, control: { ":hover": { backgroundColor: secondaryColor }, color: primaryTextColor, title: { color: primaryTextColor } }, chevron: { color: primaryTextColor } }, notifications: { root: { ".nc-notifications-list-item": { backgroundColor: secondaryColor } }, listItem: { layout: { borderRadius: "7px", color: primaryTextColor, "div:has(> .mantine-Avatar-root)": { border: "none", width: "20px", height: "20px", minWidth: "20px" }, ".mantine-Avatar-root": { width: "20px", height: "20px", minWidth: "20px" }, ".mantine-Avatar-image": { width: "20px", height: "20px", minWidth: "20px" } }, timestamp: { color: secondaryTextColor, fontWeight: "bold" }, dotsButton: { path: { fill: primaryTextColor } }, unread: { "::before": { background: unreadBackGroundColor } }, buttons: { primary: { background: primaryButtonBackGroundColor, color: primaryTextColor, "&:hover": { background: primaryButtonBackGroundColor, color: secondaryTextColor } }, secondary: { background: secondaryButtonBackGroundColor, color: secondaryTextColor, "&:hover": { background: secondaryButtonBackGroundColor, color: secondaryTextColor } } } } }, actionsMenu: { item: { "&:hover": { backgroundColor: secondaryColor } }, dropdown: { backgroundColor: primaryColor }, arrow: { backgroundColor: primaryColor, borderTop: "0", borderLeft: "0" } }, preferences: { item: { title: { color: primaryTextColor }, divider: { borderTopColor: primaryColor }, channels: { color: secondaryTextColor }, content: { icon: { color: primaryTextColor }, channelLabel: { color: primaryTextColor }, success: { color: primaryTextColor } } } }, tabs: { tabLabel: { "::after": { background: tabLabelAfterStyle }, ":hover": { color: tabLabelAfterStyle }, "[data-active]": { color: tabLabelAfterStyle } }, tabsList: { borderBottomColor: primaryColor } } };
</Accordion >
[![Edit custom-styles-novu-nc](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/custom-styles-novu-nc-2jd46m?fontsize=14&module=%2Fsrc%2Fstyles.js&moduleview=1&theme=dark)
## Customization Using Hooks
If you don't want to use our pre built component then, you can build your own notification center using hooks. `@novu/notification-center` react package provides many hooks like `useNotifications`, `useFetchNotifications`, `useUpdateUserPreferences`. Checkout all available [hooks](/notification-center/client/react/api-reference#hooks). All the hooks should be defined inside the [NovuProvider](/notification-center/client/react/api-reference#novuprovider) component. Most of the hooks are based on the `@tanstack/react-query` library.
Checkout below example on how to use `useNotifications` and `useFetchNotifications` hook
[![Edit useNotifications-useFetchNotifications-hook](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/usenotifications-usefetchnotifications-hook-2t6sgz?fontsize=14&hidenavigation=1&theme=dark)