← Back to Work
2022Component Engineering

Accessible Notification System

A toast and alert notification system that correctly uses ARIA live regions to announce status updates to screen reader users.

React · TypeScript · ARIA


Toast notifications are one of the most commonly broken accessibility patterns. They appear visually, sighted users read them, and screen reader users miss them entirely — because nobody wired up the live region.

The Pattern

An ARIA live region is a DOM element that the browser watches. When its content changes, screen readers announce the new content without the user needing to navigate to it. This is the correct mechanism for notifications.

The trap most implementations fall into is creating the live region and the message at the same time. Some browsers and screen readers only announce changes to elements that already exist in the DOM. The region must be present before the message is injected.

// The region lives permanently in the DOM, initially empty
function LiveRegion() {
  const { message } = useNotifications();
  return (
    <div
      role="status"
      aria-live="polite"
      aria-atomic="true"
      className="sr-only"
    >
      {message}
    </div>
  );
}

Polite vs Assertive

aria-live="polite" waits for the user to finish their current interaction. Use for success confirmations and informational messages.

aria-live="assertive" interrupts immediately. Use only for errors that require immediate attention — it is disruptive by design.

The Role Shorthand

role="status" is equivalent to aria-live="polite" plus aria-atomic="true". role="alert" is equivalent to aria-live="assertive". These shorthands are well-supported and more semantic.

The Outcome

Screen reader users in testing sessions consistently reported the notification system as "working correctly" — which meant they heard confirmations when actions succeeded and error details when they failed. Previously, they had received no feedback at all.