← Back to Docs
Accessibility

Screen Reader Announcement Patterns

Live-region recipes for async UI updates, form feedback, and route changes that work across NVDA, JAWS, and VoiceOver.

Polite status region

Use role="status" for non-urgent updates. The browser announces content changes after the user finishes their current task.

<div role="status" aria-live="polite">
  {message}
</div>

Assertive alert region

Use role="alert" for critical errors. Interrupts immediately.

<div role="alert">
  Form submission failed. Please try again.
</div>

Visually hidden live region

A persistent off-screen container for dynamic announcements without layout shifts.

<div
  aria-live="polite"
  className="sr-only"
  aria-atomic="true"
>
  {announcement}
</div>

Route-change announcement

Announce page title on navigation for SPA routers.

useEffect(() => {
  const region = document.getElementById("route-announcer");
  if (region) region.textContent = document.title;
}, [pathname]);

Tip: Always test with at least two screen readers. NVDA and VoiceOver handle aria-atomic differently when content is replaced vs appended.