Prebuilt Inbox Component

This guide covers the prebuilt Notification Inbox components for a Mass Notification Inbox.

native-notify ships a prebuilt Notification Inbox: a bell icon for your app header with an unread dot, and a full-screen inbox screen that opens when the bell is tapped. In mode="mass" the inbox displays your app-wide (mass) notifications — the same data returned by the getNotificationInbox function.

Quick start

Add the <NotificationInboxBell> component to your header with mode="mass" (the default):

import { NotificationInboxBell } from 'native-notify';

// Expo Router / React Navigation header:
<Stack.Screen
  name="index"
  options={{
    headerRight: () => (
      <NotificationInboxBell
        appId={yourAppId}
        appToken="yourAppToken"
        mode="mass" // default — can be omitted
      />
    ),
  }}
/>

Tapping the bell opens the built-in inbox screen, which fetches your mass notifications and shows an unread dot when there are new ones.

appId and appToken are optional on every inbox component when you set them once with NativeNotify.init() or <NativeNotifyProvider> — pass them explicitly only if you prefer.

Mass mode notes

Note:

The unread dot needs a real device. Read state is tracked per device using the device's Expo push token, so the dot only appears on a physical device that has registered a token. On Android, test on a development build — Expo Go can't mint Expo push tokens since SDK 53. On web and simulators the bell simply never shows the unread dot.

  • Delete is not available in mass mode. The mass delete endpoint removes a notification for every user, so it is an admin action handled from the Native Notify dashboard — it is intentionally not wired into the component.
  • Opening the inbox marks the fetched notifications as read, so the unread dot clears when the inbox opens.
  • The app icon badge follows the unread count — whenever the unread count refreshes, it is synced to the app icon badge with Notifications.setBadgeCountAsync(). Pass syncBadge={false} to opt out.

Props

NotificationInboxBell accepts the following props:

PropTypeDefaultDescription
appIdnumber | stringYour Native Notify App ID.
appTokenstringYour Native Notify App Token.
mode'mass' | 'indie''mass'Which inbox to load.
subIdnumber | stringRequired when mode="indie" (the user's unique ID).
takenumber20Number of notifications fetched per page.
syncBadgebooleantrueSync the unread count to the app icon badge.
colorsobjectlight/dark themePartial theme override — see Colors.
titlestring'Notifications'Inbox header title.
emptyTextstring"You're all caught up"Empty-state body text.
allowDeletebooleanPer-row delete button — only ever shown in indie mode. Mass mode never shows it.
onNotificationPress(notification) => voidCalled when a row is tapped.
onOpen() => voidIf set, called instead of opening the built-in inbox screen.
showCountbooleanfalseShow a numeric unread badge instead of a plain dot.
maxCountnumber99Badge cap — shows "99+" past it.
renderIcon({ unreadCount, color }) => nodebundled bell iconCustom bell icon.
iconSizenumber24Bell icon size.
iconStyleStyleProp<ImageStyle>Style override for the bell icon.
containerStyleStyleProp<ViewStyle>Style override for the bell container.

Colors

Colors follow the device's light/dark mode automatically. Pass any subset of the keys below in colors to override the theme:

<NotificationInboxBell
  appId={yourAppId}
  appToken="yourAppToken"
  colors={{ dot: '#EF4444', accent: '#2563EB' }}
/>
  • icon, dot, badgeText
  • background, headerBackground, card, border
  • title, text, mutedText, emptyTitle, emptyText
  • accent, delete

Custom screen and headless hook

Want your own trigger instead of the bell? Render <NotificationInboxScreen> and control the modal yourself with visible / onClose — it accepts all of the props above plus these:

PropTypeDefaultDescription
visiblebooleanWhether the inbox modal is shown.
onClose() => voidCalled when the modal is dismissed.

To build a fully custom UI, use the headless hook:

import { useNotificationInbox } from 'native-notify';

const {
  notifications,   // fetched inbox rows
  unreadCount,     // unread count for your own badge
  loading,         // initial load in progress
  refreshing,      // pull-to-refresh in progress
  loadingMore,     // next page in progress
  hasMore,         // more pages available
  error,           // error message, if any
  openInbox,       // marks fetched notifications as read
  refresh,
  refreshUnread,
  loadMore,
  deleteNotification,
} = useNotificationInbox({
  appId: yourAppId,
  appToken: 'yourAppToken',
  mode: 'mass',
  take: 20,
  syncBadge: true, // sync the unread count to the app icon badge
});

Exact pagination is available for custom UIs: getNotificationInboxPage() returns { rows, total } — the server's X-Total-Count — so "load more" is exact instead of a guess.

Inbox row data

Each row in the inbox is shaped like this:

{
  notification_id, // unique notification ID
  date,            // notification date
  title,           // notification title
  message,         // notification message
  pushData,        // data object sent with the push notification
}