Toast

Shows a brief message that stacks, follows a promise and swipes away.

Installation

$ npx shadcn@latest add @constella/toast

Usage

Render Toaster once, around your app.

import { Toaster } from "@/components/ui/toast";

<Toaster>
  <App />
</Toaster>;

Then call toast.add from anywhere, even outside React.

import { toast } from "@/components/ui/toast";

toast.add({ title: "Saved", type: "success" });

Types

Use type to add an icon. Leave it out for text only.

toast.add({ title: "Event created" });
toast.add({ title: "Saved", type: "success" });
toast.add({ title: "Couldn’t save", type: "error" });
toast.add({ title: "Running low on space", type: "warning" });
toast.add({ title: "A new version is available", type: "info" });
toast.add({ title: "Syncing…", type: "loading" });

Action

Use actionProps to add a button. Keep it to one action.

toast.add({
  title: "File deleted",
  description: "It’s in the trash for 30 days.",
  actionProps: { children: "Undo", onClick: restore },
});

Promise

Use toast.promise to show a loading toast that turns into success or error.

toast.promise(upload(files), {
  loading: { title: "Uploading…" },
  success: { title: "Done", description: "3 files uploaded." },
  error: { title: "Upload failed", description: "The connection dropped." },
});

Dismiss

Use timeout: 0 to keep a toast until it's closed. Use toast.close to close one by id, or all of them.

const id = toast.add({ title: "Read this", timeout: 0 });

toast.close(id);
toast.close();

Custom Layout

Toaster renders this tree for every toast. To change it, render your own list inside ToastProvider, ToastPortal and ToastViewport with useToastManager().

Toast
└── ToastContent
    ├── ToastIcon
    ├── ToastBody
    │   ├── ToastTitle
    │   └── ToastDescription
    ├── ToastAction
    └── ToastClose

API Reference

Every part takes sx to override its styles. The rest is Base UI's Toast.

toast

MethodDoes
toast.add(options)Shows a toast, returns its id
toast.update(id, options)Changes a toast in place
toast.close(id?)Closes one toast, or all without an id
toast.promise(promise, states)Follows a promise through its states

Options

OptionTypeDefault
titleReactNode
descriptionReactNode
type"success" | "error" | "warning" | "info" | "loading"
timeoutnumber, in ms; 0 stays until closed5000
actionPropsButton props for the action
priority"low" | "high", how urgently it's announced"low"