Notifications

Since the version stream-chat-react@13.1.0 it is possible to render notifications registered with StreamClient instance as follows

client.notifications.add({ message, origin, options }); // low-level method called by other methods - addError, addWarning ...
client.notifications.addError({ message, origin, options }); // internally appends severity 'error' to notification payload
client.notifications.addWarning({ message, origin, options }); // internally appends severity 'warning' to notification payload
client.notifications.addInfo({ message, origin, options }); // internally appends severity 'info' to notification payload
client.notifications.addSuccess({ message, origin, options }); // internally appends severity 'success' to notification payload

The component that renders these notifications is MessageListNotifications and can be customized:

<Channel MessageListNotifications={CustomMessageListNotifications}>

In order the notification text to be built and translated properly, translator functions for notification topic should be registered. See the notification translation guide for more information.

In the following sections we will explain more about the notification management done by NotificationManager.

NotificationManager

The NotificationManager is a centralized system for managing and displaying notifications. It provides a unified way to handle different types of notifications (errors, warnings, info, success) with configurable durations and behaviors.

Accessing NotificationManager

The NotificationManager is available through the StreamChat client:

const client = new StreamChat(apiKey, token);
const notificationManager = client.notifications;

Notification Severity Types

The manager supports four severity levels of notifications:

type NotificationSeverity = "error" | "warning" | "info" | "success";

Each type has a default duration of 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

The NotificationManager uses a StateStore for its state management. You can 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

It is possible to group notifications by assigning them type. This allows to treat different Notification instances in the same way. The SDK applies unified format when adding new notification types:

domain:entity:operation:result
  • domain: where the error occurred (api, validation, permission, etc.)
  • entity: what was being operated on (poll, attachment, message, etc.)
  • operation: what was being attempted (create, upload, validate, etc.)
  • result: what happened (failed, blocked, invalid, etc.)

The type examples follow:

  • validation:attachment:file:missing
  • validation:attachment:upload:blocked
  • api:attachment:upload:failed
  • api:poll:create:failed

An example of error notification that is emitted by AttachmentManager can be seen below:

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

  1. Origin Tracking
  • Always provide meaningful origin information
  • Include relevant context for debugging
  1. Duration Management
  • Use appropriate durations for different severity levels
  1. State Cleanup
  • Remove notifications when they’re no longer needed
  • Clear notifications when changing contexts
  1. Error Handling
  • Use error notifications for actual errors
  • Provide actionable information in error messages
  1. Performance
  • Clean up subscriptions when components unmount
  • Avoid excessive notification creation

© Getstream.io, Inc. All Rights Reserved.