---
title: Toast
description: "A succinct message that is displayed temporarily."
---

```tsx
import { Button } from '@/components/ui/button';
import { toast, Toaster, ToastProvider } from '@/components/ui/toast';

export default function ToastDemo() {
  return (
    <ToastProvider>
      <Button
        variant="outline"
        onClick={() =>
          toast('Scheduled: Catch up', {
            description: 'Friday, February 10 at 5:57 PM',
          })
        }
      >
        Show toast
      </Button>
      <Toaster />
    </ToastProvider>
  );
}
```

## Install

```bash
npx shadcn@latest add @madeui/toast
```

## Usage

```tsx
import { toast, Toaster, ToastProvider } from '@/components/ui/toast';

// 1. Wrap your app in <ToastProvider> and mount <Toaster /> once (e.g. in the root layout).
// 2. Call `toast` from anywhere — components, event handlers, stores:
toast('Saved', { description: 'Your changes were saved.' });
toast.success('Deployed');
toast.error('Could not save');
```

## Stacking

Toasts pile up behind the newest one (up to the provider's `limit`, 3 by
default). Hovering or focusing the stack expands it to show every toast.
Trigger the demo above a few times in a row to see it.

## Swipe to dismiss

Drag a toast down or right (touch or mouse) to dismiss it. Configure with
`<Toaster swipeDirection={['down', 'right']} />` — any of `'up' | 'down' |
'left' | 'right'`, or a single value.

## Promise

`toast.promise` shows a loading toast, then updates it in place when the
promise settles.

```tsx
import { Button } from '@/components/ui/button';
import { toast, Toaster, ToastProvider } from '@/components/ui/toast';

function save() {
  return new Promise<void>((resolve) => setTimeout(resolve, 2000));
}

export default function ToastPromise() {
  return (
    <ToastProvider>
      <Button
        variant="outline"
        onClick={() =>
          toast.promise(save(), {
            loading: 'Saving…',
            success: 'Changes saved',
            error: 'Could not save',
          })
        }
      >
        Save with toast.promise
      </Button>
      <Toaster />
    </ToastProvider>
  );
}
```

## Duration

```tsx
import { Button } from '@/components/ui/button';
import { Toaster, ToastProvider, useToast } from '@/components/ui/toast';

function DemoButton() {
  const toast = useToast();
  return (
    <Button
      variant="outline"
      onClick={() =>
        toast.add({
          title: 'Sticky toast',
          description: 'Stays for 10 seconds.',
          timeout: 10000,
        })
      }
    >
      Show sticky toast
    </Button>
  );
}

export default function ToastDuration() {
  return (
    <ToastProvider>
      <DemoButton />
      <Toaster />
    </ToastProvider>
  );
}
```

## Types

`toast.success` and `toast.error` set a `type` on the toast (mirrored as
`data-type` on the rendered element). Styling is identical across types out
of the box — since you own `components/ui/toast.tsx`, add a `[data-type="…"]`
condition to `styles.root` to color-code them.

```tsx
import * as stylex from '@stylexjs/stylex';

import { Button } from '@/components/ui/button';
import { toast, Toaster, ToastProvider } from '@/components/ui/toast';
import { space } from '@/lib/constants.stylex';

export default function ToastTypes() {
  return (
    <ToastProvider>
      <div {...stylex.props(styles.row)}>
        <Button
          variant="outline"
          onClick={() => toast('Event created', { description: 'Team sync at 3 PM.' })}
        >
          Default
        </Button>
        <Button
          variant="outline"
          onClick={() => toast.success('Changes saved')}
        >
          Success
        </Button>
        <Button
          variant="outline"
          onClick={() => toast.error('Could not save', { description: 'Try again.' })}
        >
          Error
        </Button>
      </div>
      <Toaster />
    </ToastProvider>
  );
}

const styles = stylex.create({
  row: {
    display: 'flex',
    flexWrap: 'wrap',
    gap: space.s2,
  },
});
```

## Action

Pass `actionProps` to render an action button inside the toast.

```tsx
import { Button } from '@/components/ui/button';
import { toast, Toaster, ToastProvider } from '@/components/ui/toast';

export default function ToastAction() {
  return (
    <ToastProvider>
      <Button
        variant="outline"
        onClick={() =>
          toast('Message archived', {
            actionProps: {
              children: 'Undo',
              onClick: () => toast('Message restored'),
            },
          })
        }
      >
        Archive message
      </Button>
      <Toaster />
    </ToastProvider>
  );
}
```

## Position

The stack's screen position lives in `Toaster`'s own styles; override it with
the `style` prop, same as any other component in this library.

```tsx
import * as stylex from '@stylexjs/stylex';

import { Button } from '@/components/ui/button';
import { toast, Toaster, ToastProvider } from '@/components/ui/toast';
import { space } from '@/lib/constants.stylex';

export default function ToastPosition() {
  return (
    <ToastProvider>
      <Button
        variant="outline"
        onClick={() => toast('Synced to top left')}
      >
        Show toast
      </Button>
      <Toaster style={styles.topLeft} />
    </ToastProvider>
  );
}

const styles = stylex.create({
  topLeft: {
    bottom: null,
    right: null,
    left: space.s4,
    top: space.s4,
  },
});
```

## API reference

Built on [Base UI Toast](https://base-ui.com/react/components/toast). The tables below cover the props this library adds or changes — every other prop is forwarded to the underlying Base UI part; see the [Base UI Toast API reference](https://base-ui.com/react/components/toast#api-reference) for the full list.

### toast(title, options?)

Imperative API backed by a module-level toast manager — no hook needed, works
outside React. `useToast()` remains available for the hook form
(`useToast().add({ … })`).

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `title` | `ReactNode` | — | Toast heading. |
| `description` | `ReactNode` | — | Supporting text. |
| `timeout` | `number` | — | Auto-dismiss delay in ms (Base UI default: 5000). |
| `type` | `string` | — | Toast type; `toast.success` / `toast.error` set it for you. |
| `actionProps` | `object` | — | Props for the action button (e.g. `{ children: 'Undo', onClick }`). |

Also available: `toast.promise(promise, { loading, success, error })`,
`toast.update(id, options)`, `toast.close(id)`.

### Toaster

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `swipeDirection` | `Direction \| Direction[]` | `['down', 'right']` | Direction(s) a toast can be swiped to dismiss. |

`Toaster` renders the styled toast stack; to change its look, edit `components/ui/toast.tsx` directly — you own the source.
