Notifications
Notifications are the short messages the SDK shows after something happens: "Message pinned" after a pin, "Error uploading attachment" after a failed upload. This page covers what users see and when, and points to the pages that explain each part.
What users get
The user flags a message in a thread:
- "Message has been successfully flagged" slides in at the bottom of the thread, with a success icon.
- Three seconds after it appears, it slides out.
- A screen reader reads "Success notification: Message has been successfully flagged".
If the flag fails, an error notification appears in the same place: the server's error message, or "Error adding flag" when there is none. A screen reader reads it at once, interrupting what it was saying.
What users see follows a few rules:
- Where. A notification appears in the part of the screen where it happened: the channel, the thread, the channel list, the thread list, or an open dialog.
- One at a time. Each part of the screen shows one notification and queues the rest. A notification without a duration, such as one with a button the user has to press, jumps the queue.
- How long. A notification stays three seconds by default, counted from when it appears. One without a duration stays until the user closes it, and shows a close button.
- In the user's language. The text is translated with the rest of the UI.
A lost connection is different. Chat publishes "Waiting for network…" or "Reconnecting…", but no part of the screen shows it until the app renders a banner. Connection status covers that.
How it works across the layers
State: client.notifications
Every notification lives in client.notifications, the client's notification manager. It holds the list in client.notifications.store, and the default duration for each severity: error, warning, info and success.
stream-chat publishes there itself when an upload, a send, an edit, a poll vote or a jump to a message goes wrong. Each notification has a type, such as api:attachment:upload:failed, that says what it's about. Publishing notifications explains the manager, the types and the full list of what stream-chat publishes.
UI: lists, the notification and the announcer
- Publishing. The React components publish with
useNotificationApi(): message actions, channel-list row actions, channel details, polls, location sharing, reactions and audio. The hook tags each notification for the part of the screen the component sits in, called its panel. - Showing. A
NotificationListserves each panel: the message list of a channel or a thread,ChannelNavigation,ThreadListand each open modal. A list shows the notifications tagged for its panel, one at a time, and starts each one's countdown when it appears. - Rendering one.
Notificationrenders a notification: its icon, its translated text, its action buttons and a close button. - Announcing.
Chatrenders aNotificationAnnouncer, which reads every new notification to screen readers, whether or not a list shows it.
A notification tagged system, such as the lost-connection one, is shown by no list. The app renders it with useSystemNotifications().
Displaying notifications explains the panels and how notifications reach them, the queue, translation, system notifications, and what each React component publishes.
Layout
The layout decides nothing about notifications. A notification follows the component that published it: a flag inside a Thread goes to that thread's list, wherever the layout puts the thread.
Turning it on or off
Notifications are always on, and nothing in client.config or the dashboard turns them off. What a user can trigger depends on their capabilities: a user who can't flag messages has no Flag action, so never sees "Message has been successfully flagged".
To show none, pass Chat a display filter that rejects every notification. The announcer reads notifications whether a list shows them or not, so replace it too:
import type { PropsWithChildren } from "react";
import { Chat, WithComponents } from "stream-chat-react";
import type { NotificationDisplayFilter } from "stream-chat-react";
// No list shows a notification.
const hideAllNotifications: NotificationDisplayFilter = () => false;
// Screen readers hear none either.
const SilentAnnouncer = () => null;
const overrides = { NotificationAnnouncer: SilentAnnouncer };
export const App = ({ children }: PropsWithChildren) => (
<WithComponents overrides={overrides}>
<Chat client={client} notificationDisplayFilter={hideAllNotifications}>
{children}
</Chat>
</WithComponents>
);WithComponents wraps Chat here because Chat reads the announcer from the components above it.
Customizing
Publishing your own
Call addNotification from useNotificationApi() in a component inside Chat. The notification goes to the panel the component sits in:
import { useNotificationApi } from "stream-chat-react";
export const CopyLinkButton = ({ link }: { link: string }) => {
const { addNotification } = useNotificationApi();
const copy = async () => {
await navigator.clipboard.writeText(link);
addNotification({
emitter: "CopyLinkButton",
message: "Link copied",
severity: "success",
type: "app:link:copy:success",
});
};
return (
<button onClick={copy} type="button">
Copy link
</button>
);
};Routing notifications shows how to send it to another panel. Outside React, publish with client.notifications.add(), as in Publishing a notification.
How long notifications stay
The durations are client settings, set per severity. Naming one keeps the others at three seconds:
client.config.set({
client: { notifications: { durations: { error: 8000 } } },
});Configuration explains client.config, and Severity, actions and durations covers durations for one notification and notifications that stay.
Where and how they look
- Move the lists to the top, or change which queued notification shows next: Replacing the list or a notification.
- Change colors and shapes with CSS: Styling.
- Keep some notifications out of some panels: Display filter.
What they say
The text of a built-in notification comes from a translation key. Override the key, or register a translator for the notification's type: Translating notifications.
What screen readers hear
Replace NotificationAnnouncer to skip some notifications or reword them: Customizing notification announcements.
A banner for system notifications
Render the lost-connection notification, and system notifications of your own, as a banner: Connection status and the System notification banner recipe.
Reference
- Publishing notifications:
client.notifications, the notification types and whatstream-chatpublishes. - Displaying notifications: the
NotificationListandNotificationprops, and what the React components publish. - Notification hooks:
useNotificationApi,useNotificationsanduseSystemNotifications. - Chat: the
notificationDisplayFilterprop. - ComponentContext: the
Notification,NotificationListandNotificationAnnounceroverride keys. - Configuration tree:
client.notifications.durations.