All hooks / Component helpers
useAnnounce
Returns announce(message, politeness?), which reads a message to screen reader users without moving focus or showing anything on screen. The same message twice is announced twice.
'polite' (default) waits until the screen reader is idle; 'assertive' interrupts it, for errors only. One hidden live region per politeness is shared by all components and removed when the last one unmounts. The function is stable. Nothing runs on the server.
Import
import { useAnnounce } from '@vincent.ri/react-tils'
// or only this hook
import { useAnnounce } from '@vincent.ri/react-tils/useAnnounce'Usage
const announce = useAnnounce()
const [copy] = useCopyToClipboard()
return <button onClick={async () => (await copy(url)) && announce('Link copied')}>Copy link</button>Live demo
Turn on a screen reader (VoiceOver: ⌘F5), then press a button.
When to use it
The result of an action isn't announced by itself: "Copied", "Added to cart", "3 results", "Message sent", "Saved", or a validation error that appears away from focus.
When not to
Focus moves to the new content (a dialog, an inline error with aria-describedby), or the text is in an element that already has role="status" or role="alert"; screen readers read those anyway.
API
function useAnnounce(): (message: string, politeness?: Politeness) => voidReturns announce(message, politeness?).
Types
export type Politeness = "polite" | "assertive";Browser support
| Uses | Chrome | Edge | Firefox | Safari | Chrome Android | Safari iOS |
|---|---|---|---|---|---|---|
| requestAnimationFrameWidely available | 24+ | 12+ | 23+ | 7+ | 25+ | 7+ |
First version with support, from MDN's compatibility data (web-features 3.42.0, @mdn/browser-compat-data 8.1.5).
Coming from another library?
Other libraries call this useAnnouncer, useLiveAnnouncer, LiveAnnouncer.