client.notifications.add({ message, origin, options }); // low-level method called by addError/addWarning/...
client.notifications.addError({ message, origin, options }); // adds severity: 'error'
client.notifications.addWarning({ message, origin, options }); // adds severity: 'warning'
client.notifications.addInfo({ message, origin, options }); // adds severity: 'info'
client.notifications.addSuccess({ message, origin, options }); // adds severity: 'success'Notifications
Starting in stream-chat-react@13.1.0, you can render notifications created by the StreamClient:
MessageListNotifications renders these notifications. You can swap it with a custom component:
<Channel MessageListNotifications={CustomMessageListNotifications}>Best Practices
- Use severity levels to keep notifications meaningful.
- Keep notification copy concise and actionable.
- Prefer custom
MessageListNotificationsonly for layout or branding changes. - Translate notifications via the notification topic for consistency.
- Avoid over-notifying; throttle noisy sources.
To build and translate notification text, register translator functions for the notification topic. See the notification translation guide.
The sections below cover notification management in NotificationManager.
NotificationManager
NotificationManager centralizes notification creation and display across severities (error, warning, info, success) with configurable duration and behavior.
Accessing NotificationManager
NotificationManager is available on the StreamChat client:
const client = new StreamChat(apiKey, token);
const notificationManager = client.notifications;Notification Severity Types
The manager supports four severity levels:
type NotificationSeverity = "error" | "warning" | "info" | "success";Each severity defaults to 3000ms (3 seconds).
Adding Notifications
Basic Usage
// Add a notification with default severity (info)
const id = client.notifications.add({
message: "Operation completed",
origin: {
emitter: "MyComponent",
context: {
/* any relevant context */
},
},
});Specific Severity Methods
// Add error notification
client.notifications.addError({
message: "Operation failed",
origin: { emitter: "MyComponent" },
});
// Add warning notification
client.notifications.addWarning({
message: "Operation might fail",
origin: { emitter: "MyComponent" },
});
// Add info notification
client.notifications.addInfo({
message: "Operation in progress",
origin: { emitter: "MyComponent" },
});
// Add success notification
client.notifications.addSuccess({
message: "Operation succeeded",
origin: { emitter: "MyComponent" },
});Advanced Options
client.notifications.add({
message: "Custom notification",
origin: { emitter: "MyComponent" },
options: {
severity: "warning",
duration: 8000, // Override default duration
actions: [
{
label: "Retry",
handler: () => {
/* handle retry */
},
},
],
metadata: {
/* custom data */
},
},
});Managing Notifications
Removing Notifications
// Remove specific notification
client.notifications.remove(notificationId);
// Clear all notifications
client.notifications.clear();Accessing Current Notifications
// Get all notifications
const allNotifications = client.notifications.notifications;
// Get notifications by severity
const errors = client.notifications.error;
const warnings = client.notifications.warning;
const infos = client.notifications.info;
const successes = client.notifications.success;Subscribing to State Changes
NotificationManager uses a StateStore. Subscribe to state changes:
// Subscribe to all notification changes
const unsubscribe = client.notifications.store.subscribe(
(nextValue, previousValue) => {
// Handle notification state changes
console.log("New notifications:", nextValue.notifications);
console.log("Previous notifications:", previousValue?.notifications);
},
);
// Clean up subscription
unsubscribe();State Structure
The NotificationManager state has the following structure:
type NotificationState = {
notifications: Array<{
id: string;
message: string;
origin: {
emitter: string;
context?: Record<string, unknown>;
};
severity: NotificationSeverity;
createdAt: number;
actions?: Array<{
label: string;
handler: () => void;
metadata?: Record<string, unknown>;
}>;
expiresAt?: number;
metadata?: Record<string, unknown>;
originalError?: Error;
type?: string;
}>;
};Notification Types
You can group notifications by assigning type. The SDK uses a unified format:
domain:entity:operation:result- domain: where it occurred (api, validation, permission)
- entity: what it affected (poll, attachment, message)
- operation: what was attempted (create, upload, validate)
- result: outcome (failed, blocked, invalid)
Examples:
validation:attachment:file:missingvalidation:attachment:upload:blockedapi:attachment:upload:failedapi:poll:create:failed
Example error notification emitted by AttachmentManager:
client.notifications.addError({
message: `The attachment upload was blocked`,
origin: {
emitter: "AttachmentManager",
context: { attachment, blockedAttachment: localAttachment },
},
options: {
type: "validation:attachment:upload:blocked",
metadata: {
reason: localAttachment.localMetadata.uploadPermissionCheck?.reason,
},
},
});Best Practices
- Origin Tracking
- Provide a clear
origin.emitter - Include minimal context needed for debugging
- Duration Management
- Match duration to severity and UX needs
- State Cleanup
- Remove notifications that no longer apply
- Clear notifications when the UI context changes
- Error Handling
- Use error notifications for real failures
- Make messages actionable
- Performance
- Unsubscribe on unmount
- Avoid spamming notifications