Skip to content
Devix Open Source

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" with aria-atomic="true" — the whole message is read, not the changed word.
  • Errors are role="alert": they interrupt. Set politeness per 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: 0 keeps a toast until it is dismissed — the right choice for anything that needs a decision.

Motion and colour

  • prefers-reduced-motion drops the slide, the progress animation and the spinner.
  • forced-colors mode 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