Notifications accessibility

Notifications reach users of screen readers and braille displays without them looking at the screen. Use this page to know what assistive technology announces for a notification, and how to choose and reword what's announced. Accessibility across the SDK is on Accessibility.

Notification announcements

Notifications are the messages the SDK and your code publish to client.notifications, for example with addNotification from useNotificationApi(). Notifications UI shows where they appear and how they look.

NotificationAnnouncer reads each new one aloud:

  • An error interrupts, and every other severity waits its turn.
  • By default it says the severity first: "Success notification: Message pinned", "Error notification: Error adding flag". The text after the prefix is translated, the prefix isn't.
  • Notifications already in the list when it mounts aren't read.
  • It reads every notification, including those no list shows, such as the lost-connection system notification, and those a display filter hides.

The Notification component's message is also a live region: assertive for errors and polite otherwise. addNotification takes ariaLive to change that for one notification. NotificationAnnouncer ignores it and goes by severity.

Customizing notification announcements shows how to choose and reword what's read.

Customizing notification announcements

Chat renders NotificationAnnouncer, which reads new notifications aloud, as Notification announcements describes. Replace it to choose which notifications it reads and what it says. Chat reads it from the components above it, so pass the override with WithComponents around Chat:

import type { PropsWithChildren } from "react";
import { Chat, NotificationAnnouncer, WithComponents } from "stream-chat-react";
import type {
  NotificationAnnouncementBuilder,
  NotificationAnnouncementFilter,
} from "stream-chat-react";

// Skip informational notifications.
const notificationFilter: NotificationAnnouncementFilter = (notification) =>
  notification.severity !== "info";

// Errors start with "Error:", the rest keep the default wording.
const buildNotificationAnnouncement: NotificationAnnouncementBuilder = ({
  defaultMessage,
  notification,
  translatedMessage,
}) =>
  notification.severity === "error"
    ? `Error: ${translatedMessage}`
    : defaultMessage;

const CustomNotificationAnnouncer = () => (
  <NotificationAnnouncer
    buildNotificationAnnouncement={buildNotificationAnnouncement}
    notificationFilter={notificationFilter}
  />
);

const overrides = { NotificationAnnouncer: CustomNotificationAnnouncer };

export const App = ({ children }: PropsWithChildren) => (
  <WithComponents overrides={overrides}>
    <Chat client={client}>{children}</Chat>
  </WithComponents>
);

The builder receives:

  • translatedMessage: the notification's text, translated as the notification itself shows it;
  • defaultMessage: what the announcer says by default, the translated text after a severity prefix, such as "Error notification: Error adding flag";
  • notification: the notification.

Return an empty string to say nothing for a notification.

Used in