Branding & Styling Reference
The Inbox component is fully themeable through theappearance prop. This reference covers every level of customization — from dropping in a base theme to building dynamic, severity-aware, brand-perfect styles.
Inspiration: inbox.novu.co showcases pre-built variants like Notion and Reddit.
The appearance prop
| Key | Purpose |
|---|---|
baseTheme | Start from a predefined theme (e.g. dark) |
variables | Global design tokens (colors, fonts, radius, severity colors) |
elements | Per-element styles — string, style object, or callback |
icons | Replace built-in icons with your own React components |
baseTheme and variables are set, variables win.
Styles are auto-injected into <head>. If the Inbox is rendered inside a shadow DOM, styles are scoped to that shadow root.
Base themes
Novu currently ships adark base theme:
baseTheme + variables to start from a theme and tweak just a few tokens:
Variables (design tokens)
| Variable | Description |
|---|---|
colorBackground | Inbox background |
colorForeground | Primary text color |
colorPrimary | Accent color for interactive elements |
colorPrimaryForeground | Text on primary surfaces |
colorSecondary | Less prominent surfaces |
colorSecondaryForeground | Text on secondary surfaces |
colorCounter | Background of unread counters |
colorCounterForeground | Text inside counters |
colorNeutral | Borders and neutral surfaces |
colorShadow | Shadow color |
fontSize | Base font size |
borderRadius | Border radius applied across elements |
colorSeverityHigh | High-severity accent |
colorSeverityMedium | Medium-severity accent |
colorSeverityLow | Low-severity accent |
Element-level styling
Each key inappearance.elements accepts:
- String of class names — CSS, CSS Modules, Tailwind
- Style object — inline CSS
- Callback —
(context) => stringreturning class names, evaluated on every render with the relevant context (notification, unreadCount, preference, schedule)
Inline style object
Tailwind classes
CSS Modules
Dynamic styling via callbacks
Callbacks receive contextual data and return class names. Use them for state-aware styles (unread count, notification severity, payload data):Common element keys
| Element | Key |
|---|---|
| Notification container | notification |
| Notification subject text | notificationSubject |
| Notification body text | notificationBody |
| Notification image / icon | notificationImage |
| Notification date | notificationDate |
| Notification list | notificationList |
| Primary action button | notificationPrimaryAction__button |
| Secondary action button | notificationSecondaryAction__button |
| Archive button | notificationArchive__button |
| Snooze button | notificationSnooze__button |
| Mark unread button | notificationUnread__button |
| Bell icon | bellIcon |
| Bell container | bellContainer |
| Bell dot (unread indicator) | bellDot |
| Popover content | popoverContent |
| Preferences button | preferences__button |
| Schedule container | scheduleContainer |
| Schedule header | scheduleHeader |
| Schedule body / table | scheduleBody, scheduleTable |
To find any element key, inspect the DOM. Class names starting withnv-(visible just before a 🔔 emoji in DevTools) map to keys inelements. Drop thenv-prefix.
Callback context signatures
| Element group | Context |
|---|---|
bellIcon, bellContainer, bellDot, bellSeverityGlow, severity*__bellContainer | { unreadCount: { total: number; severity: Record<string, number> } } |
notification, notification*, severity*__notification*, notificationDot | { notification: Notification } |
notificationList, notificationListContainer | { notifications: Notification[] } |
workflow*, channelsContainer, channelName | { preference: Preference } |
channelContainer, channelLabelContainer, channelIconContainer, channelLabel, channelSwitchContainer, channel__icon | { preference?: Preference; preferenceGroup?: { name: string; preferences: Preference[] } } |
preferencesGroup* | { preferenceGroup: { name: string; preferences: Preference[] } } |
preferencesContainer | { preferences?: Preference[]; groups: Array<{ name: string; preferences: Preference[] }> } |
schedule*, dayScheduleCopy*, timeSelect* | { schedule?: Schedule } |
Severity styling
Notifications expose three severity levels:high, medium, low. Styling can be applied through variables (global colors) or elements (precise overrides).
Severity variables
| Variable | Description |
|---|---|
colorSeverityHigh | High severity color |
colorSeverityMedium | Medium severity color |
colorSeverityLow | Low severity color |
Severity element keys
| Key | Description |
|---|---|
severityHigh__bellContainer | Bell container for high severity |
severityMedium__bellContainer | Bell container for medium severity |
severityLow__bellContainer | Bell container for low severity |
bellSeverityGlow | Base bell glow style |
severityGlowHigh__bellSeverityGlow | Glow for high severity |
severityGlowMedium__bellSeverityGlow | Glow for medium severity |
severityGlowLow__bellSeverityGlow | Glow for low severity |
severityHigh__notification | High severity notification row |
severityMedium__notification | Medium severity notification row |
severityLow__notification | Low severity notification row |
notificationBar | Vertical bar on the left of a notification |
severityHigh__notificationBar | Bar for high severity |
severityMedium__notificationBar | Bar for medium severity |
severityLow__notificationBar | Bar for low severity |
By default the bell takes the color of the highest-severity unread notification.
Custom icons
Replace built-in icons with anything that renders to a React node:Icon keys
| Key | Description |
|---|---|
arrowDown | Down arrow used in drop-downs and expandable sections |
arrowDropDown | Drop-down arrow in menus and selectors |
arrowLeft | Left arrow used in pagination/navigation |
arrowRight | Right arrow used in pagination/navigation |
bell | Notification bell in the header |
chat | Chat channel icon in preferences |
check | Checkmark for selected items |
clock | Date/time display |
cogs | Settings/preferences icon |
dots | Three-dot menu in notification items |
email | Email channel icon in preferences |
inApp | In-app channel icon in preferences |
markAsArchived | Archive notification |
markAsArchivedRead | Archive + read |
markAsRead | Mark as read |
markAsUnread | Mark as unread |
markAsUnarchived | Unarchive |
push | Push channel icon in preferences |
sms | SMS channel icon in preferences |
trash | Delete |
unread | Unread indicator |
unsnooze | Unsnooze indicator |
To find more keys, inspect the DOM for class names starting withnv-containing a 🖼️ emoji. The part afternv-is the icon key.
Responsive Inbox
<Drawer>.