Toasts
.mdImperative toasts that stack in the corner, fan out on hover, update in place from loading to done, and blur away on dismiss.
toastnotificationsonnerfeedbackloadingstack
Installation
$npx shadcn@latest add @geturui/toast
Usage
usage.tsx
1// app/layout.tsx — mount the stack once
2import { Toaster } from "@/components/ui/toast";
3
4export default function RootLayout({ children }: { children: React.ReactNode }) {
5 return (
6 <html lang="en">
7 <body>
8 {children}
9 <Toaster />
10 </body>
11 </html>
12 );
13}
14
15// anywhere in a client component
16import { toast } from "@/components/ui/toast";
17
18async function publish() {
19 const id = toast({ tone: "loading", title: "Publishing" });
20 await fetch("/api/publish", { method: "POST" });
21 toast({ id, tone: "success", title: "Published", description: "Your page is live." });
22}
Props
| Prop | Type | Default | Description |
|---|---|---|---|
toast(options) | (t: { id?; tone?; title; description?; action?; duration? }) => string | — | Push a toast, or update one by passing its id. Returns the id. |
toast.success / .error / .info | (title: ReactNode, description?: ReactNode) => string | — | Shorthands for the common tones. |
toast.dismiss | (id: string) => void | — | Remove a toast now. |
tone | "success" | "danger" | "info" | "warning" | "loading" | "info" | Icon and live-region politeness. Loading toasts never auto-dismiss. |
action | { label: string; onClick: () => void } | — | Optional text button under the description. |
duration | number | 4200 | Milliseconds before auto-dismiss; 0 keeps it until closed. |
position | "bottom-right" | "bottom-center" | "bottom-right" | Toaster only. Where the stack sits. |
Accessibility
- The stack is an aria-live="polite" region; error toasts use role="alert", others role="status".
- Hovering the stack pauses every timer, so there's time to read or reach the action.
- Each toast has a labelled Dismiss button reachable by keyboard.