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

> Fulldev UI for React. The `@fulldev` registry in `components.json` points at `https://ui.full.dev/r/react/styles/{style}/{name}.json`; see [installation](/react/docs/installation.md).

```tsx title="src/components/examples/toast/toast-demo.tsx"
"use client"

import { Button } from "@/components/ui/button"
import { toast } from "@/components/ui/toast"

export function ToastDemo() {
  function showToast() {
    const id = toast.add({
      title: "Event created",
      description: "Sunday, December 3 at 9:00 AM",
      actionProps: {
        children: "Undo",
        onClick() {
          toast.close(id)
        },
      },
    })
  }

  return (
    <Button variant="outline" onClick={showToast}>
      Show Toast
    </Button>
  )
}
```

## Installation

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

Add the `Toaster` to the root layout:

```tsx title="app/layout.tsx"
import { Toaster } from "@/components/ui/toast"

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <main>{children}</main>
        <Toaster />
      </body>
    </html>
  )
}
```

## Usage

```tsx
import { toast } from "@/components/ui/toast"
```

```tsx
toast.add({
  title: "Event created",
  description: "Sunday, December 3 at 9:00 AM",
})
```

## Types

Set the `type` option to render a status icon. The built-in renderer recognizes `success`, `info`, `warning`, `error`, and `loading`.

```tsx title="src/components/examples/toast/toast-types.tsx"
"use client"

import { Button } from "@/components/ui/button"
import { toast } from "@/components/ui/toast"

export function ToastTypes() {
  return (
    <div className="flex flex-wrap gap-2">
      <Button
        variant="outline"
        onClick={() => toast.add({ description: "Event has been created." })}
      >
        Default
      </Button>
      <Button
        variant="outline"
        onClick={() =>
          toast.add({
            type: "success",
            description: "Event has been created.",
          })
        }
      >
        Success
      </Button>
      <Button
        variant="outline"
        onClick={() =>
          toast.add({
            type: "info",
            description: "Arrive 10 minutes before the event.",
          })
        }
      >
        Info
      </Button>
      <Button
        variant="outline"
        onClick={() =>
          toast.add({
            type: "warning",
            description: "The event cannot start before 8:00 AM.",
          })
        }
      >
        Warning
      </Button>
      <Button
        variant="outline"
        onClick={() =>
          toast.add({
            type: "error",
            description: "The event could not be created.",
            priority: "high",
          })
        }
      >
        Error
      </Button>
    </div>
  )
}
```

## Action

Pass button props with `actionProps` to render an action.

```tsx
const id = toast.add({
  title: "Event created",
  actionProps: {
    children: "Undo",
    onClick() {
      toast.close(id)
    },
  },
})
```

## Promise

Use `toast.promise` to update one toast as an asynchronous task moves through loading, success, and error states.

```tsx title="src/components/examples/toast/toast-promise.tsx"
"use client"

import { Button } from "@/components/ui/button"
import { toast } from "@/components/ui/toast"

export function ToastPromise() {
  function showToast() {
    toast.promise(
      new Promise<{ name: string }>((resolve) => {
        window.setTimeout(() => resolve({ name: "Event" }), 2000)
      }),
      {
        loading: "Creating event…",
        success: (data) => `${data.name} created.`,
        error: "Could not create event.",
      }
    )
  }

  return (
    <Button variant="outline" onClick={showToast}>
      Create Event
    </Button>
  )
}
```

## Custom layout

`createToastManager`, `ToastProvider`, `ToastViewport` and the `Toast` parts build a second toast stack with its own layout.

```tsx title="Usage of @fulldev/toast (react/gallery/ui/toast.tsx, not installed)"
import * as React from "react"

import { Button } from "@/components/ui/button"
import {
  createToastManager,
  Toast,
  toast,
  ToastAction,
  ToastClose,
  ToastContent,
  ToastDescription,
  Toaster,
  ToastPortal,
  ToastProvider,
  ToastTitle,
  ToastViewport,
  useToastManager,
} from "@/components/ui/toast"

// A second manager with its own provider and viewport, for the custom layout.
const customToast = createToastManager()

function CustomToastList() {
  const { toasts } = useToastManager()
  return toasts.map((item) => (
    <Toast key={item.id} toast={item}>
      <ToastContent className="items-start">
        <div className="flex min-w-0 flex-1 flex-col gap-1">
          <ToastTitle />
          <ToastDescription />
          <div className="mt-2 flex gap-2">
            <ToastAction />
            <ToastClose render={<Button variant="ghost" size="sm" />}>
              Dismiss
            </ToastClose>
          </div>
        </div>
      </ToastContent>
    </Toast>
  ))
}

function CustomToastButton() {
  const manager = useToastManager()
  return (
    <Button
      variant="outline"
      onClick={() =>
        manager.add({
          title: "Invitation sent",
          description: "Ada can now edit this site.",
          timeout: 0,
          actionProps: {
            children: "Undo",
            onClick: () => manager.add({ title: "Invitation withdrawn" }),
          },
        })
      }
    >
      Custom layout
    </Button>
  )
}

function Example({
  title,
  children,
}: {
  title: string
  children: React.ReactNode
}) {
  return (
    <section className="flex flex-col gap-3">
      <h2 className="text-sm font-medium text-muted-foreground">{title}</h2>
      <div className="flex flex-wrap items-start gap-4">{children}</div>
    </section>
  )
}

export default function Demo() {
  return (
    <div className="flex flex-col gap-10 p-6">
      <Toaster />
      <Example title="Default">
        <Button
          variant="outline"
          onClick={() =>
            toast.add({
              title: "Event created",
              description: "Sunday, December 3 at 9:00 AM",
            })
          }
        >
          Show toast
        </Button>
        <Button
          variant="outline"
          onClick={() =>
            toast.add({
              title: "Page deleted",
              description: "You can restore it for 30 days.",
              actionProps: {
                children: "Undo",
                onClick: () => toast.add({ title: "Page restored" }),
              },
            })
          }
        >
          With action
        </Button>
      </Example>
      <Example title="Types">
        {(["success", "info", "warning", "error", "loading"] as const).map(
          (type) => (
            <Button
              key={type}
              variant="outline"
              className="capitalize"
              onClick={() =>
                toast.add({
                  type,
                  title: `A ${type} toast`,
                  description: "Its icon follows the type.",
                })
              }
            >
              {type}
            </Button>
          )
        )}
      </Example>
      <Example title="Promise and close all">
        <Button
          variant="outline"
          onClick={() =>
            toast.promise(
              new Promise<string>((resolve) =>
                setTimeout(() => resolve("Homepage"), 2000)
              ),
              {
                loading: { title: "Publishing" },
                success: (name) => ({ title: `${name} is live` }),
                error: { title: "Publishing failed" },
              }
            )
          }
        >
          Publish
        </Button>
        <Button variant="ghost" onClick={() => toast.close()}>
          Close all
        </Button>
      </Example>
      <Example title="Custom provider, viewport and layout">
        <ToastProvider toastManager={customToast} limit={2}>
          <CustomToastButton />
          <ToastPortal>
            <ToastViewport className="sm:right-auto sm:left-4">
              <CustomToastList />
            </ToastViewport>
          </ToastPortal>
        </ToastProvider>
      </Example>
    </div>
  )
}
```

## API Reference

Source: [`react/src/components/ui/toast.tsx`](https://github.com/fulldotdev/ui/blob/main/react/src/components/ui/toast.tsx)

See the [Base UI Toast documentation](https://base-ui.com/react/components/toast) for manager options, stacking, swipe dismissal, and the primitive API.

## Install what this page shows

```bash
npx shadcn@latest add @fulldev/toast-examples @fulldev/toast
```
