Skip to main content
Two levels of custom rendering, in increasing order of control. Replace parts of the built-in inbox, its list item, header, or states, while it keeps managing the list, sync, and pagination. Web SDKs only. Or build your own UI from the message data and actions directly, which every platform supports including mobile. Reach for the first when the default inbox is nearly right and one element is not. Reach for the second when your app already has a list component you want to keep. covers theming, which handles most cases without either.

Replace parts of the inbox

Render slots are web SDKs only (React, Vue, Angular, Web Components). On iOS, Android, Flutter, and React Native, use theming or build your own UI below.
Provide a renderer for any slot: header, listItem, emptyState, loadingState, errorState, or paginationItem. Each renderer receives the relevant message or state. Slots you leave out use the built-in element.
A Courier Inbox with a custom header reading Notifications and a 2 new badge, and custom list items showing sender avatars and roles

An inbox with a custom header and custom list items, while the SDK still manages the list.

Build your own UI

You do not have to render CourierInbox at all. Every SDK exposes the message data and actions directly, so you can build the whole UI while the SDK keeps everything synced. The setup is the same everywhere:
  1. Start the feed.
  2. Render your own UI from the messages.
  3. Toggle read (or archive) on interaction.
  4. Tear down the listener when the view goes away.
The one difference is how the feed starts:
  • Web SDKs: nothing loads automatically. Register the feeds, open the realtime connection, then load: registerFeeds(defaultFeeds())listenForUpdates()load().
  • Mobile SDKs: adding an inbox listener loads the first page for you, if you have first. (refreshInbox() is only for pull-to-refresh.)
The listener (and the web useCourier hook) also reports loading, errors, unread count, and pagination state. See Data and actions for the full surface. On the mobile SDKs and Web Components, remove the listener when your view is torn down. The React, Vue, and Angular wrappers do this for you.

Data and actions

The pattern above uses a subset of what each SDK exposes. Here is the full surface: the data you read (messages, unread count, pagination state) and the actions you call (mark read, archive, paginate, refresh). The built-in inbox calls these for you. On the web, read the data from the useCourier hook (React and Vue), the CourierInboxDatastore (Web Components), or the CourierService (Angular). On mobile, an inbox listener pushes the data to you and the actions take a messageId.