React hooks and components for managing ARIA live regions. Announce dynamic content changes to screen reader users with a simple, declarative API.
npm install @umxr/react-aria-liveWrap your app with LiveRegionProvider and use the useAnnounce hook to make announcements:
import { LiveRegionProvider, useAnnounce } from '@umxr/react-aria-live';
function App() {
return (
<LiveRegionProvider>
<SaveButton />
</LiveRegionProvider>
);
}
function SaveButton() {
const announce = useAnnounce();
const handleSave = async () => {
await saveData();
announce('Document saved successfully');
};
return <button onClick={handleSave}>Save</button>;
}Context provider that manages live region announcements. Wrap your app with this component.
<LiveRegionProvider clearOnUnmount={true}>{children}</LiveRegionProvider>| Prop | Type | Default | Description |
|---|---|---|---|
clearOnUnmount |
boolean |
true |
Clear pending announcements when provider unmounts |
Hook for making announcements programmatically.
const announce = useAnnounce();
// Polite announcement (default)
announce('Items updated');
// Assertive announcement (interrupts)
announce('Error: Failed to save', { priority: 'assertive' });
// With delay
announce('Auto-saved', { delay: 1000 });
// Clear queue before announcing
announce('New message', { clearQueue: true });Options:
| Option | Type | Default | Description |
|---|---|---|---|
priority |
'polite' | 'assertive' |
'polite' |
Announcement urgency |
clearQueue |
boolean |
false |
Clear pending announcements first |
delay |
number |
0 |
Delay in milliseconds |
Hook for accessing the announcement queue state.
const { queue, clear, isPending } = useAnnouncementQueue();| Property | Type | Description |
|---|---|---|
queue |
Announcement[] |
Current pending announcements |
clear |
() => void |
Clear all pending announcements |
isPending |
boolean |
Whether announcements are pending |
Declarative component for content that should be announced when it changes.
<LiveRegion priority="polite" atomic>
{statusMessage}
</LiveRegion>| Prop | Type | Default | Description |
|---|---|---|---|
priority |
'polite' | 'assertive' | 'off' |
'polite' |
Announcement urgency |
atomic |
boolean |
false |
Announce entire region on any change |
relevant |
'additions' | 'removals' | 'text' | 'all' |
- | Types of changes to announce |
role |
'alert' | 'status' | 'log' | 'marquee' | 'timer' |
- | ARIA role |
visible |
boolean |
true |
Whether content is visually visible |
as |
ElementType |
'div' |
HTML element to render |
className |
string |
- | CSS class |
Component for one-off announcements without rendering visible content.
{
isSuccess && <Announce message="Form submitted successfully" />;
}| Prop | Type | Default | Description |
|---|---|---|---|
message |
string |
required | Message to announce |
priority |
'polite' | 'assertive' |
'polite' |
Announcement urgency |
Renders live region elements that can be placed inside modals or other focus-trapped containers.
By default, the library creates announcer elements at the document body level. However, screen readers may not announce content from live regions outside a focused modal. Use the Announcer component inside your modal to ensure announcements are heard.
import { Announcer } from '@umxr/react-aria-live';
function Modal({ children }) {
return (
<div role="dialog" aria-modal="true">
<Announcer />
{children}
</div>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
id |
string |
auto-generated | ID prefix for announcer elements |
How it works:
- All
Announcercomponents subscribe to the same announcement queue - When
useAnnounce()is called, ALL mounted announcers receive the message - The screen reader hears the announcer that's in the active focus context
Pre-configured components for common patterns:
Assertive announcements with role="alert".
<Alert>Payment failed. Please try again.</Alert>Polite status updates with role="status".
<Status>{itemCount} items in cart</Status>Sequential content like chat messages with role="log".
<Log>
{messages.map((m) => (
<p key={m.id}>{m.text}</p>
))}
</Log>The package exports test utilities for verifying announcements in your tests:
import {
getAnnouncements,
clearMockAnnouncements,
} from '@umxr/react-aria-live/test';
test('announces on save', async () => {
render(<SaveButton />);
await userEvent.click(screen.getByRole('button'));
expect(getAnnouncements()).toContain('Document saved');
});Test utilities:
| Function | Description |
|---|---|
getAnnouncements() |
Get all announcement messages |
getLastAnnouncement() |
Get the most recent announcement |
hasAnnouncement(message) |
Check if a message was announced |
clearMockAnnouncements() |
Clear the announcement history |
getAnnouncementsByPriority(priority) |
Get announcements filtered by priority |
- Use polite by default - Reserve
assertivefor critical, time-sensitive information - Keep messages concise - Screen reader users benefit from brief, clear announcements
- Avoid duplicate announcements - The library automatically deduplicates within 150ms
- Test with real screen readers - Automated tests can't catch all accessibility issues
- Chrome (latest 2 versions)
- Firefox (latest 2 versions)
- Safari (latest 2 versions)
- Edge (latest 2 versions)
MIT