Styling the Inbox component

Learn how to style the pre built Inbox component

Customization Hierarchy

The Inbox component is built to allow for multiple layers of styling, which allows the specificity required to style the Inbox to meet the requirements of your use case.

Depending on the level of customization you need, you can choose to style the inbox using one of the following approaches:

You can see Styling in action on the Inbox Playground with common themes like Notion, Reddit and more!

Appearance Prop

The appearance prop can be used to customise the Inbox. It has three main keys: baseTheme, variables and elements.

  • Variables: Global styling variables that apply to multiple elements within the inbox.
  • Elements: Elements are the individual UI components that make up the Inbox.
  • Base theme: This is the base theme applied to the <Inbox />. It has the same keys as appearance. Used for applying base themes like dark.

Variables

Variables are used to define global styling properties that can be reused throughout the inbox. You might want to use variables to the styling of multiple components at once, for example, if you want to change the border radius of all the components at once, you can do so by updating the colorPrimary variable, which will modify the CTA buttons, unseen counter and etc...

PropTypeDefault
borderRadius?
string
-
fontSize?
string
-
colorShadow?
string
-
colorNeutral?
string
-
colorCounterForeground?
string
-
colorCounter?
string
-
colorSecondaryForeground?
string
-
colorSecondary?
string
-
colorPrimaryForeground?
string
-
colorPrimary?
string
-
colorForeground?
string
-
colorBackground?
string
-
Appearance Variables

Styling Variables

You can override the default elements by passing your own styles or CSS classes to the elements object.

import { Inbox } from '@novu/react';
const appearance = {
  variables: {
    colorBackground: 'yellow',
  },
};
 
<Inbox appearance={appearance} />;

Elements

The elements object allows you to define styles for these components. Each key corresponds to a component, and the value is an object containing style properties or you can also pass your css classes. Here's a list of available elements that can be styled using the elements object in your appearance configuration:

Finding element selectors

You can inspect the elements you want to customize using the browser's dev tools, each element has a unique selector that you can use to style starting with nv-.

Strip the nv- prefix when and add it to the elements object. For example, to style the nv-notificationPrimaryAction__button element, you can add the following to the elements object:

const appearance = {
  elements: {
    notificationPrimaryAction__button: {
      backgroundColor: 'red',
    },
  },
};
Finding Element Selectors

Any selector that appears before the 🔔 emoji, can be targeted via the elements property in the appearance prop (stripping the nv- prefix). You can also use TS autocomplete to find the available elements.

Customizing icons

The icons property in the appearance prop lets you customize any icon used in the Inbox component. This is useful when you want to:

  • Match the bell icon with your host app's navbar icon set
  • Use your own icon library, such as react-icons or Material Icons to maintain a consistent design system
  • Modify all icons to fit your application's visual style

Finding icon keys

Each icon in the Inbox component is identified by a unique key. To find the key for a specific icon, inspect the element in your browser’s developer tools. Icon elements include a class name that starts with nv- and often feature a 🖼️ emoji for easier identification.

The portion of the class name following nv- is the icon key. For example, an element with the class nv-cogs has the icon key cogs, which you can use in the appearance.icons property to override that icon with a custom renderer.

Once you’ve identified the key, provide a function that returns a React component to replace the default icon:

import { Inbox } from '@novu/react';
import { RiSettings3Fill, RiArrowDownLine, RiNotification3Fill} from 'react-icons/ri';
 
const appearance = {
    icons: {
      cogs: () => <RiSettings3Fill />,
      arrowDown: () => <RiArrowDownLine />,
      bell: () => <RiNotification3Fill />,
    },
  };
 
export function Novu() {
  return (
    <Inbox
      applicationIdentifier="YOUR_APPLICATION_IDENTIFIER"
      subscriber="YOUR_SUBSCRIBER_ID"
      appearance={appearance}
    />
  );
}

This lets you fully customize the visual presentation of the Inbox component’s icons using your preferred design system.

Available icon keys

Click to view all available icon keys
Icon KeyDescription
bellThe notification bell icon in the header
clockUsed in the date/time display for notifications
arrowDropDownDropdown arrow in various menus and selectors
dotsMore options menu (three dots) in notification items
markAsReadIcon for marking notifications as read
cogsSettings/preferences icon in the header
trashDelete/remove icon for notifications
markAsArchivedIcon for archiving notifications
markAsArchivedReadIcon for marking notifications as archived and read
markAsUnreadIcon for marking notifications as unread
markAsUnarchivedIcon for unarchiving notifications
unsnoozeIcon for unsnoozed notifications
arrowRightRight arrow used in pagination and navigation
arrowLeftLeft arrow used in pagination and navigation
unreadIndicator for unread notifications
smsSMS channel icon in notification preferences
inAppIn-app channel icon in notification preferences
emailEmail channel icon in notification preferences
pushPush notification channel icon in preferences
chatChat channel icon in notification preferences
checkCheckmark icon used for selected items
arrowDownDown arrow used in dropdowns and expandable sections

Dark theme

No need to implement a custom dark theme. Just import our premade dark theme and use it via the baseTheme option in appearance.

import { Inbox } from '@novu/react';
import { dark } from '@novu/react/themes';
import { useTheme } from 'next-themes';
 
export function Novu() {
  const { resolvedTheme } = useTheme();
 
  return (
    <Inbox
      applicationIdentifier="YOUR_APPLICATION_IDENTIFIER"
      subscriber="YOUR_SUBSCRIBER_ID"
      appearance={{ baseTheme: resolvedTheme === 'dark' ? dark : undefined }}
    />
  );
}

Bring your own CSS

You can override the default elements by passing your own styles or CSS classes to the elements object.

Using Tailwind CSS

You can also use Tailwind CSS classes to style the Inbox components. You can pass the classes directly to the elements object.

import { Inbox } from '@novu/react';
 
const appearance = {
  elements: {
    bellIcon: 'p-4 bg-white rounded-full',
    notification: 'bg-white rounded-lg shadow-sm hover:shadow-md hover:bg-gray-50',
  },
};
 
export function Novu() {
  return (
    <Inbox
      applicationIdentifier="YOUR_APPLICATION_IDENTIFIER"
      subscriber="YOUR_SUBSCRIBER_ID"
      appearance={appearance}
    />
  );
}

Using CSS Modules

You can also use CSS Modules to style the Inbox components. Here's how you can do it:

  • Create a CSS module file (e.g. styles.module.css) with the styles you want to apply to the Inbox components.
.bellIcon {
  padding: 1rem;
  background-color: white;
  border-radius: 50%;
}
 
.bellIcon:hover {
  background-color: #f9fafb;
}
 
.notification {
  background-color: white;
  border-radius: 0.5rem;
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
}
 
.notification:hover {
  background-color: #f9fafb;
}
  • Import the CSS module file and pass the classes to the elements object.
import { Inbox } from '@novu/react';
import styles from './styles.module.css';
 
const appearance = {
  elements: {
    bellIcon: styles.bellIcon,
    notification: styles.notification,
  },
};
 
export function Novu() {
  return (
    <Inbox
      applicationIdentifier="YOUR_APPLICATION_IDENTIFIER"
      subscriber="YOUR_SUBSCRIBER_ID"
      appearance={appearance}
    />
  );
}

Using Styles Object

You can also use a styles object to style the Inbox components. You can pass the styles directly to the elements object.

import { Inbox } from '@novu/react';
 
const appearance = {
  elements: {
    bellIcon: {
      padding: '1rem',
      backgroundColor: 'white',
      borderRadius: '50%',
    },
    notification: {
      backgroundColor: 'white',
      borderRadius: '0.5rem',
      boxShadow: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
    },
  },
};
 
export function Novu() {
  return (
    <Inbox
      applicationIdentifier="YOUR_APPLICATION_IDENTIFIER"
      subscriber="YOUR_SUBSCRIBER_ID"
      appearance={appearance}
    />
  );
}

Render subject and body with bold text

By default, the Inbox notification text for the subject and body is rendered in a normal font weight. To highlight important words or phrases within your notification messages, you can wrap the desired subject or body text in double asterisks (**). Here's an example of how you can do this using the Novu Framework:

await step.inApp('inbox', async () => {
  return {
    subject: '**A new member joined the team!**',
    body: '**John Doe** joined the team! Say hello and help them feel at home',
  };
});

Note: When rendering the custom notification component, you will need to parse the text and apply the bold styling accordingly.

Currently, the Inbox component only support bold text. Other text formatting options will be available in the future. To learn, refer to the Novu Framework in-app step documentation.

Render notification component

You can render your own custom notification item component by passing a renderNotification prop to the Inbox or Notifications component. This lets you style and render more complex notification items.

import { Inbox } from '@novu/react';
import { CustomNotification } from './CustomNotification';
 
<Inbox
  renderNotification={(notification) => {
    return <CustomNotification notification={notification} />;
  }}
/>;

The Inbox styles placement

The <Inbox /> component automatically injects its styles into the <head> tag of the HTML document when rendered in the standard DOM.

However, when rendered inside a shadow DOM, it detects the shadow context and injects styles into the shadow root instead. This ensures proper style encapsulation and prevents leakage or conflicts with global styles without any additional configuration.