Toast
A brief notification in a stack at the corner of the screen, with status icons, an optional action and progress for async work.
npx prodular-ui add toastStatus types
Pass type success, info, warning or error. Hover the stack to expand it.
"use client"
import { Button } from "@/components/ui/button"import { createToastManager, Toaster } from "@/components/ui/toast"
const manager = createToastManager()
const examples = [ { label: "Success", type: "success", title: "Invoice INV-2048 sent", description: "Northgate Logistics will get it at ap@northgate.co.", }, { label: "Info", type: "info", title: "Export is being prepared", description: "We'll email you a link when the CSV is ready.", }, { label: "Warning", type: "warning", title: "You're at 90% of your seats", description: "216 of 240 seats are in use.", }, { label: "Error", type: "error", title: "Payment failed", description: "The card ending in 4242 was declined.", },]
export default function ToastStatus() { return ( <Toaster toastManager={manager}> <div className="flex flex-wrap items-center justify-center gap-3"> {examples.map((e) => ( <Button key={e.type} variant="outline" onClick={() => manager.add({ type: e.type, title: e.title, description: e.description })} > {e.label} </Button> ))} </div> </Toaster> )}Action and progress
actionProps adds a button. promise() shows a spinner, then the result.
"use client"
import { Button } from "@/components/ui/button"import { createToastManager, Toaster } from "@/components/ui/toast"
const manager = createToastManager()
function wait(ms: number) { return new Promise((resolve) => setTimeout(resolve, ms))}
export default function ToastAction() { return ( <Toaster toastManager={manager}> <div className="flex flex-wrap items-center justify-center gap-3"> <Button variant="outline" onClick={() => { const id = manager.add({ title: "3 issues archived", description: "They're hidden from every view.", actionProps: { children: "Undo", onClick: () => manager.close(id), }, }) }} > Archive issues </Button> <Button variant="outline" onClick={() => manager.promise(wait(2200), { loading: { title: "Publishing release notes", description: "Relay 4.2 for all workspaces." }, success: { title: "Release notes published", description: "Customers see them in What's new." }, error: { title: "Could not publish", description: "Try again in a minute." }, }) } > Publish with progress </Button> </div> </Toaster> )}Anatomy
// Once, in the root layout<Toaster />
// Anywheretoast.add({ type: "success", title: "Invoice sent", description: "Northgate Logistics will get it at ap@northgate.co.", actionProps: { children: "Undo", onClick: undoSend },})Guidance
Use it when
- Use to confirm that something happened in the background: saved, sent, exported, archived.
- Offer Undo with actionProps instead of asking for confirmation first.
- Use promise() for work that takes more than a second.
Avoid
- Errors that block the user. Show them inline next to the field or as an Alert.
- More than one toast for the same event.
- Long text. One title of a few words, one sentence of description.
Rules for AI agents
Published in llms-full.txt, the registry and the MCP server, so coding agents follow them when they build with this component.
- Mount <Toaster /> once near the root of the app. Then call toast.add({ title, description, type }) from anywhere.
- Use type success, info, warning, error or loading. destructive is accepted as an alias of error.
- Write the title as the outcome in past tense: Invoice sent, 3 issues archived.
- Add actions with actionProps: { children: "Undo", onClick }. Do not render buttons inside description.
- For a separate stack, create one with createToastManager() and pass it to Toaster as toastManager.
API
toast.add
| Prop | Type | Default | Description |
|---|---|---|---|
| type | "success" | "info" | "warning" | "error" | "destructive" | "loading" | Picks the status icon. | |
| title / description | ReactNode | One short title and an optional sentence. | |
| actionProps | ButtonProps | Renders an outline action button below the description. | |
| timeout | number | 5000 | Milliseconds before it closes. 0 keeps it open. |
Toaster
| Prop | Type | Default | Description |
|---|---|---|---|
| toastManager | ToastManager | toast | The manager this stack listens to. |
| limit | number | 3 | Visible toasts before older ones are hidden. |
Installation
The Prodular UI CLI adds the source to components/ui with everything it depends on. In a project that already uses shadcn/ui, the shadcn CLI installs it from the Prodular registry too. See Installation for the first setup.
npx prodular-ui add toast# or, with the registry in components.jsonnpx shadcn@latest add @prodular/toast