Components

Transient, non-blocking confirmations — "Saved", "Request sent". ToastProvider wraps a subtree so it can raise toasts and renders the bottom-right viewport that stacks them; any descendant calls useToast() to add one. Not a place for actions the user must take — use a Dialog for that.

Install

npx shadcn@latest add @alix/toast

Preview

Usage

// App root:
<ToastProvider>{children}</ToastProvider>

// Anywhere inside:
const toast = useToast();
toast.add({
  title: "Request sent",
  description: "The client has been notified.",
  type: "success",
});

Examples

01

Success and error intents

Toast type controls the intent accent while the title and description carry the operational message.

<ToastProvider>
  <div className="flex flex-wrap gap-3">
    <Button
      onClick={() =>
        toast.add({
          title: "Plan saved",
          description: "The engagement workspace is up to date.",
          type: "success",
        })
      }
    >
      Show success
    </Button>
    <Button
      variant="outline"
      onClick={() =>
        toast.add({
          title: "Export failed",
          description: "Try again once the data refresh is complete.",
          type: "error",
        })
      }
    >
      Show error
    </Button>
  </div>
</ToastProvider>
02

After a panel action

A local ButtonGroup can raise non-blocking feedback while the panel remains available for more edits.

Client briefing

Confirm that the latest risks and next steps are ready for the team.

<ToastProvider>
  <div className="w-full max-w-sm border border-border p-4">
    <div className="mb-4 flex flex-col gap-1">
      <h3 className="text-sm font-medium text-foreground">Client briefing</h3>
      <p className="text-sm text-muted-foreground text-pretty">
        Confirm that the latest risks and next steps are ready for the team.
      </p>
    </div>
    <ButtonGroup
      primaryAction={
        <Button
          onClick={() =>
            toast.add({
              title: "Briefing saved",
              description: "The team can now review the updated note.",
              type: "success",
            })
          }
        >
          Save briefing
        </Button>
      }
      secondaryAction={
        <Button
          variant="outline"
          onClick={() =>
            toast.add({
              title: "Preview sent",
              description: "A test notification was sent to your inbox.",
              type: "success",
            })
          }
        >
          Send preview
        </Button>
      }
    />
  </div>
</ToastProvider>

When to use it

Use it for

  • Non-blocking confirmations after save, send, export, or request actions.
  • Short success or error feedback that does not require a decision.
  • One provider near an app or product subtree so descendants can raise messages.

Reach for something else

  • Blocking confirmations or destructive decisions — use Dialog instead.
  • Inline validation errors next to a control — use Field instead.
  • Persistent status, health, or phase labels — use Badge or Progress instead.

Props

PropTypeDefaultDescription
ToastProviderchildrenWraps a subtree and renders the stacking viewport. Put it once near the root of an app or product page.
useToast()() => { add, toasts, … }Hook (Base UI's useToastManager). Call inside the provider tree; toast.add(options) raises a toast.
add(options){ title, description?, type? }title/description are the copy; type ("success" | "error") drives the left accent border.

See also