> ## Documentation Index
> Fetch the complete documentation index at: https://v0.x-docs.novu.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Customizing Notification Center

> 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 Customization

`<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](/notification-center/client/react/api-reference#popovernotificationcenter). If you are looking for a component without popover use regular `<NotificationCenter>` component. Checkout [props](/notification-center/client/react/api-reference#notificationcenter) of this component. Few selected customization options are explained below:-

### Implementing custom bell icon

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.

```jsx theme={null}
<PopoverNotificationCenter colorScheme="dark">
  {({ unseenCount }) => (
    <CustomBell
      unseenCount={unseenCount}
      colorScheme="dark"
      unseenBadgeBackgroundColor="#FFFFFF"
      unseenBadgeColor="#FF0000"
    />
  )}
</PopoverNotificationCenter>
```

### Dark mode support

To support dark mode in your application the notification center component can receive a `colorScheme` prop that can receive either `dark` or `light` mode.

```tsx theme={null}
<PopoverNotificationCenter colorScheme={"dark" || "light"}>
  {({ unseenCount }) => <NotificationBell unseenCount={unseenCount} />}
</PopoverNotificationCenter>
```

### Popover positioning

Use `position`  and `offset` prop to position the popover relative to the Bell icon

```jsx theme={null}
<PopoverNotificationCenter position="left-start" offset={20}>
  {({ unseenCount }) => <NotificationBell unseenCount={unseenCount} />}
</PopoverNotificationCenter>
```

### Header, Footer and Empty state

Use `header`, `footer` and `emptyState` prop to customize the header, footer and empty state of notification center.

```jsx theme={null}
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>;
```

### Notification item

Use the listItem prop to show custom notification items.

```jsx theme={null}
<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>
```

### Customize the UI language

If you want to use a language other than english for the UI, the `NovuProvider` component can accept an optional `i18n` prop.

```typescript theme={null}
<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

```typescript theme={null}
i18n = "en";
```

<Accordion title="Supported Language">
  * `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)
</Accordion>

* Translation object

```typescript theme={null}
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",
  },
}}

```

<Tip>Novu uses *`en`* as the default value for i18n</Tip>

### Customization using `styles` prop

`styles` prop can be used to cutomise styling of each component of notification center. Read more about [styles prop](/notification-center/client/react/api-reference#styles)

```javascript theme={null}
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
      }
    }
  }
}
```

<Accordion title="Customizing styles">
  ```javascript theme={null}
  const primaryColor = "white";
  const secondaryColor = "#AFE1AF";
  const primaryTextColor = "#0C0404";
  const secondaryTextColor = "#494F55";
  const unreadBackGroundColor = "#869F9F";
  const primaryButtonBackGroundColor = unreadBackGroundColor;
  const secondaryButtonBackGroundColor = "#C6DFCD";
  const dropdownBorderStyle = "2px solid #AFE1AF";
  const tabLabelAfterStyle = "#AFE1AF !important";
  const ncWidth = "350px !important";

  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)
