Guide
Accessibility
A notification nobody hears is not a notification.
What screen readers get
- The region is a
<section aria-label="Notifications">, so it is reachable from a landmark list. - Each toast is
role="status"witharia-atomic="true"— the whole message is read, not the changed word. - Errors are
role="alert": they interrupt. Setpolitenessper toast to override either way. toast.loading(…)announces once;toast.update(id, …)announces the new state rather than adding a second toast, so "Saving…" becomes "Saved" in one announcement.
Keyboard and pointer
- Toasts never steal focus. They are after the page content in the DOM, so Tab reaches the buttons when the user wants them.
- Tab into a toast pauses its timer, so a keyboard user is not racing the clock to reach "Undo".
- Every toast carries a dismiss button by default — react-hot-toast's most-requested feature, and still open there.
- Swipe works with a mouse, a pen or a thumb; it is never the only way to dismiss.
Time
- The countdown pauses on hover, on focus inside the toast, and while the tab is hidden. A message that arrives while you are in another tab is still there when you come back.
duration: 0keeps a toast until it is dismissed — the right choice for anything that needs a decision.
Motion and colour
prefers-reduced-motiondrops the slide, the progress animation and the spinner.forced-colorsmode draws real borders and uses system colours.- Colour is never the only signal: every type has its own icon and its own words.
Over a modal
A modal <dialog> makes everything outside it inert — visible, but dead to the pointer. When a modal
is open the toasts move inside it, keeping their buttons, swipe and hover-pause working, and move back
out when it closes.
Updated 12 Sep 2026