A short, auto-dismissing notification.

'use client'

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

export default function ToastDemo() {
  return (
    <Button
      variant="outline"
      onClick={() =>
        toast({
          title: 'Event created',
          description: 'Friday, February 10, 2028 at 5:57 PM',
        })
      }
    >
      Show toast
    </Button>
  )
}

Built on Base UI

Installation

pnpm dlx shadcn@latest add https://kagadmodyaa.vercel.app/r/toast.json

Needs a React + Tailwind project set up with shadcn. Copies the component source straight into your project, so you can edit it.

Usage

// once, near the root of the app (e.g. app/layout.tsx)
import { Toaster } from '@/components/ui/toast'
<Toaster />

// anywhere else
import { toast } from '@/components/ui/toast'

toast('Saved!')
toast({ title: 'Event created', description: 'Friday, February 10 at 5:57 PM' })

// an action button
toast({ title: 'File archived', actionProps: { children: 'Undo', onClick: () => restore() } })

// loading -> success / error
toast.promise(save(), {
  loading: { title: 'Saving…' },
  success: { title: 'Saved' },
  error: { title: 'Could not save' },
})

toast.dismiss() // close them all; toast.dismiss(id) closes one

Examples

Stacked, with an action

'use client'

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

const messages = [
  { title: 'Invoice sent', description: 'INV-204 was emailed to Acme Co.' },
  { title: 'Comment added', description: 'Ada replied on “Homepage redesign”.' },
  { title: 'File archived', description: 'brand-assets.zip moved to the archive.' },
]

/** Fire a few in a row: they stack behind the newest. Hover or focus the stack to fan it out; swipe to dismiss. */
export default function ToastStacked() {
  return (
    <div className="flex flex-wrap items-center justify-center gap-2">
      <Button
        variant="outline"
        onClick={() =>
          messages.forEach(message =>
            toast({
              ...message,
              timeout: 0,
              actionProps: { children: 'Undo', onClick: () => toast('Undone.') },
            }),
          )
        }
      >
        Show 3 toasts
      </Button>
      <Button variant="ghost" onClick={() => toast.dismiss()}>
        Clear all
      </Button>
    </div>
  )
}

Promise

'use client'

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

function save(shouldFail: boolean) {
  return new Promise<string>((resolve, reject) =>
    setTimeout(() => (shouldFail ? reject(new Error('Network error')) : resolve('Project')), 1800),
  )
}

/** `toast.promise` shows a loading toast, then swaps it for the outcome. */
export default function ToastPromise() {
  return (
    <div className="flex flex-wrap items-center justify-center gap-2">
      <Button
        variant="outline"
        onClick={() =>
          toast.promise(save(false), {
            loading: { title: 'Saving…', description: 'Uploading your changes.' },
            success: name => ({ title: 'Saved', description: `${name} is up to date.` }),
            error: () => ({ title: 'Could not save', description: 'Check your connection and try again.' }),
          })
        }
      >
        Save project
      </Button>
      <Button
        variant="outline"
        onClick={() =>
          toast.promise(save(true), {
            loading: { title: 'Saving…', description: 'Uploading your changes.' },
            success: { title: 'Saved' },
            error: error => ({ title: 'Could not save', description: error.message }),
          })
        }
      >
        Fail on purpose
      </Button>
    </div>
  )
}

API Reference

NameTypeDefaultDescription
toast(input)string | ToastOptions—Queues a toast. A string is shown as the description; an object may set title, description, type and timeout.
ToastOptions.actionPropsButtonHTMLAttributes—Adds an action button to the toast: children is its label, onClick runs when pressed.
toast.promise(promise, options)(Promise, { loading, success, error }) => Promise—Shows a loading toast and replaces it with the success or error toast when the promise settles. Each option is a string or toast options; success and error may be functions of the result or error.
toast.dismiss(id?)(id?: string) => void—Closes one toast by the id toast() returned, or all of them.
ToastOptions.timeoutnumber5000Milliseconds before auto-dismissing. 0 disables it.
Toastercomponent—Renders the toast viewport for the whole app — mount it once. Toasts stack behind the newest; hover or focus the stack to fan it out, and swipe a toast sideways or down to dismiss it.