# NotificationList

> **Info:** This is release candidate documentation for **Stream Chat React Native SDK v10**. For the latest stable version, see the [latest version (v9)](https://getstream.io/chat/docs/sdk/react-native/).

`NotificationList` shows the in-app notifications of one part of the app as a snackbar, one notification at a time. It reads them from `client.notifications`, keeps those tagged for its notification target, and renders each with the `Notification` key of `ComponentsContext`. [Displaying notifications](https://getstream.io/chat/docs/sdk/react-native/v10/ui/customizing/displaying-notifications/) explains targets, routing and translation, and [Publishing notifications](https://getstream.io/chat/docs/sdk/react-native/v10/state/publishing-notifications/) the store.

## Best practices

- Render a list inside a notification target: an SDK surface, or a `NotificationTargetProvider` of your own. Without a target and without `panel` and `hostId`, the list shows nothing.
- Render one list per target. Two lists for the same target pick the same notification and show it twice.
- Replace the SDK's lists through the `NotificationList` key, and spread the props you receive: `MessageList` passes `bottomOffset` and `filter`.
- Keep `filter` cheap. It runs for every notification of the target each time the store changes.
- Give the list's parent the size of the area it covers. The list is positioned absolutely inside it.

## Where the SDK renders it

| Surface                                   | Renders                                | Target                                                            |
| ----------------------------------------- | -------------------------------------- | ----------------------------------------------------------------- |
| `MessageList` and `MessageFlashList`      | the `NotificationList` key             | the `Channel` or `Thread` around them                             |
| `ChannelList`                             | the `NotificationList` key             | `channel-list`, with the list's `notificationHostId`              |
| `ThreadList`                              | the `NotificationList` key             | `thread-list`, with the list's `notificationHostId`               |
| `ChannelDetails`, its forms and its lists | `NotificationList` itself, not the key | `channel-details`, one host for the screen and one for each modal |

`MessageList` passes `bottomOffset` while the composer floats over the list, so the snackbar stays above it. With pending uploads on, it passes `filter={excludeCanceledUploadNotifications}`, which hides the upload failures a user causes by removing an attachment while it uploads.

## Behavior

The list asks `useNotificationListController()` for the notification to show:

1. A notification without a `duration`, such as a `loading` one, shows first. Otherwise the newest one shows.
2. Every other notification for the target is removed from the store. There's no queue.
3. The countdown of the shown notification starts when it shows, so one that waits for its list doesn't expire unseen. A notification with actions stays at least 5 seconds.
4. The list registers its target as the latest one mounted. A notification published with no target, outside a composer and outside `runWithNotificationTarget`, goes to the latest mounted list. See [Routing notifications](https://getstream.io/chat/docs/sdk/react-native/v10/ui/customizing/displaying-notifications/#routing-notifications).
5. When the list unmounts, every notification for its target is removed.

System notifications, the ones with the `system` tag, never show in a list.

The list renders the `Notification` key with the notification, `onDismiss` that removes it, and `showClose` for a notification without a `duration`. The notification animates in from `enterFrom`, or from the direction in its `metadata.entryDirection` or `origin.context.entryDirection`, and animates out the same way. A notification of a new `type` animates in again; one that replaces another of the same `type` doesn't.

The list is absolutely positioned and centered, 16 points from the edge it's anchored to and from both sides, above the other content of its parent. It has the accessibility label "Notifications", the `notifications.list.accessibilityLabel` key.

## Props

| Prop                | Type                                | Default    | Description                                                                                                                                               |
| ------------------- | ----------------------------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `panel`             | `NotificationTargetPanel`           |            | The kind of surface the list serves. With `hostId`, the exact target. Alone, the nearest provider's target if its panel matches, and no target otherwise. |
| `hostId`            | `string`                            |            | The host the list serves. Only used together with `panel`.                                                                                                |
| `filter`            | `NotificationListFilter`            |            | `(notification) => boolean`, applied after the target. A notification it rejects isn't shown, and isn't removed while the list is mounted.                |
| `enterFrom`         | `NotificationListEnterFrom`         | `'bottom'` | The side notifications animate in from: `'bottom'`, `'top'`, `'left'` or `'right'`.                                                                       |
| `verticalAlignment` | `NotificationListVerticalAlignment` | `'bottom'` | The edge the list is anchored to: `'bottom'` or `'top'`.                                                                                                  |
| `bottomOffset`      | `number`                            |            | Added to the distance from the bottom edge. Only applies with `verticalAlignment="bottom"`.                                                               |
| `topOffset`         | `number`                            |            | Added to the distance from the top edge. Only applies with `verticalAlignment="top"`.                                                                     |

Without `panel` and `hostId`, the list serves the target of the nearest `NotificationTargetProvider`.

## Theming

The theme's `notificationList.container` styles the list. The offsets apply after it, so a `bottom` or `top` in the theme is replaced while an offset is passed. Each notification is styled by the `notification` key: see [Notification components](https://getstream.io/chat/docs/sdk/react-native/v10/component-reference/notifications/notification-components/#theming).

## Examples

### A list for a screen of your own

```tsx title="src/SettingsScreen.tsx"
import { Text, View } from "react-native";
import {
  NotificationList,
  NotificationTargetProvider,
} from "stream-chat-react-native";

export const SettingsScreen = () => (
  <NotificationTargetProvider hostId="settings" panel="settings">
    <View style={{ flex: 1 }}>
      <Text>Settings</Text>
      <NotificationList enterFrom="top" topOffset={8} verticalAlignment="top" />
    </View>
  </NotificationTargetProvider>
);
```

Notifications published with `useNotificationApi()` inside the provider, or with `target: { panel: "settings", hostId: "settings" }` from anywhere, show in this list.

### Only errors in the channel list

```tsx title="src/channelListNotifications.tsx"
import type { Notification } from "stream-chat";
import { NotificationList } from "stream-chat-react-native";
import type {
  ComponentOverrides,
  NotificationListProps,
} from "stream-chat-react-native";

const isError = (notification: Notification) =>
  notification.severity === "error";

const ErrorsOnlyList = (props: NotificationListProps) => (
  <NotificationList {...props} filter={isError} />
);

// Pass these to a WithComponents around ChannelList only.
export const channelListNotificationOverrides: ComponentOverrides = {
  NotificationList: ErrorsOnlyList,
};
```

A `WithComponents` around `ChannelList` alone keeps the message lists on the default key, so their `filter` isn't replaced.

## Related

- [Notification components](https://getstream.io/chat/docs/sdk/react-native/v10/component-reference/notifications/notification-components/): `Notification`, `NotificationIcon` and `NotificationTargetProvider`.
- [Notification hooks](https://getstream.io/chat/docs/sdk/react-native/v10/reference/hooks/notification-hooks/#usenotificationlistcontroller): `useNotificationListController`, to render notifications your own way.
- [Notifications](https://getstream.io/chat/docs/sdk/react-native/v10/features/app-experience/notifications/): the feature end to end.

---

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react-native/v10/component-reference/notifications/notification-list/](https://getstream.io/chat/docs/sdk/react-native/v10/component-reference/notifications/notification-list/).