Components
Toast
Transient, non-blocking feedback. Powered by Sonner; the Toaster is already mounted at the app root — call toast() from anywhere.
When to usefor transient feedback the operator can miss without consequences — "saved", "copied", "undo".
Import
import { toast } from "sonner"Setup
Mount the Toaster once at the app root. It takes its theme as a prop — the library component is framework-free, so the host reads the theme and passes it in.
// app/toaster.tsx — your side of the boundary
"use client";
import { useTheme } from "next-themes";
import type { ToasterProps } from "sonner";
import { Toaster as EfniToaster } from "@ravnhq/efni/sonner";
export function Toaster(props: ToasterProps) {
const { theme = "system" } = useTheme();
return <EfniToaster theme={theme as ToasterProps["theme"]} {...props} />;
}
// app/layout.tsx
<Toaster />Variants
import { toast } from "sonner";
toast("Mission MB-4472 saved.");
toast.success("Waypoint reached.", { description: "…" });
toast.error("Mission aborted.", { description: "…" });With action
toast("Draft saved.", {
action: { label: "Undo", onClick: () => toast.success("Reverted.") },
});Do & don't
Confirm actions the operator can safely miss — save, copy, dispatch — with a quick toast.
Don't put a decision or destructive confirmation in a toast — use Alert dialog for anything that can't be reversed.
Accessibility
- Sonner posts to a polite live region so screen readers announce the content without stealing focus.
- Alt+T (Sonner default) focuses the toast region for keyboard users.
- Keep the message short — assistive tech will read it as one utterance.
Guidelines
Do
- Lead with what happened (Saved), then optionally include when/who in the description.
- Provide Undo for reversible actions — it removes the need for a confirm dialog.
- Match tone to outcome — success for saves, error for failures. Info sparingly.
Don't
- Don't fire more than one toast per operator action.
- Don't use toast for validation errors on a form — surface them inline via FormMessage.
- Don't stack toasts to hint at progress — use Progress instead.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
…props | ToasterProps | — | Everything Toaster passes to the element it renders. |
toast(message, options?) | (string | ReactNode, options?) => id | — | Fire a default toast. Returns an id for later dismiss/update. |
toast.success / .info / .warning / .error | same signature | — | Tone-specific helpers, each with a matching icon. |
options.description | string | ReactNode | — | Secondary line shown under the message. |
options.action | { label, onClick } | — | Inline action button (e.g. Undo). |
<Toaster theme> | "light" | "dark" | "system" | "system" | Theme for the mounted Toaster. Passed in by the host app — the library component reads no theme hook of its own. |
options.duration | number | 4000 | Auto-dismiss delay, milliseconds. Use Infinity to keep it until clicked. |