Skip to content

Overlays & navigation

Toast

Toasts confirm that something happened without interrupting the work: an invoice sent, a payment failed, an export ready. Mount one Toaster, then call toast() from any event handler or async function. Toasts stack in a corner, dismiss themselves after five seconds, pause while hovered or focused, and are announced by screen readers through a live region.

On this page

Usage

components/ui/toast.tsx
// app/layout.tsx: mount onceimport { Toaster } from "@/components/ui/toast"; <body>  {children}  <Toaster position="bottom-right" /></body> // anywhereimport { toast } from "@/components/ui/toast"; toast.success("Invoice sent", { description: "INV-2041 is on its way." });

Examples

Variants

Success, error, info and warning carry an icon in their status color; the default toast is text only.

With an action

One action, usually Undo. Clicking it runs the callback and dismisses the toast. Don't put the only way to do something in a toast: it goes away.

INV-2041 is active.

Loading and promises

toast.promise shows a spinner while the promise is pending and turns into a success or error toast in place.

Persistent and updating

duration: Infinity keeps a toast until it is closed. Reusing an id replaces the toast instead of stacking a copy.

Props

toast()

  • toast(title | options)=> iddefault: —Default toast. Returns its id.
  • toast.success / error / info / warning / loading(title, options?) => iddefault: —Same, with a variant. Loading toasts stay until updated or dismissed.
  • toast.promise(promise, { loading, success, error }) => promisedefault: —Loading toast that resolves to success or error. Messages can be functions of the result.
  • toast.dismiss(id?) => voiddefault: —Close one toast, or all of them without an id.
  • useToast()() => toastdefault: —The same API as a hook.

ToastOptions

  • titlerequiredReactNodedefault: —One short sentence: what happened.
  • descriptionReactNodedefault: —Details or the next step.
  • variant"default" | "success" | "error" | "info" | "warning" | "loading"default: "default"Icon and live-region urgency.
  • action{ label, onClick }default: —One button, e.g. Undo.
  • durationnumberdefault: 5000Milliseconds before auto-dismiss. Infinity keeps it open.
  • idstringdefault: —Reuse to update a toast in place.

Toaster

  • position"top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right"default: "bottom-right"Corner the stack grows from.
  • maxnumberdefault: 4Toasts visible at once; older ones wait their turn.
  • ToastProvider{ children, position?, max? }default: —Alternative that wraps your app and renders the Toaster after it.

Accessibility

  • Toasts render inside a labelled region (“Notifications (F8)”) with aria-live="polite", so new messages are read without stealing focus. Error toasts use role="alert" and are announced right away.
  • Press F8 to move focus to the newest toast; Tab reaches its action and the dismiss button, which is labelled “Dismiss notification”.
  • Auto-dismiss pauses while the pointer is over the stack or focus is inside it, giving everyone time to read and act (WCAG 2.2.1).
  • Status is never color alone: every variant has an icon and words. The region sits in the top layer, so toasts stay visible above open dialogs.

Suggested