Skip to content
Components

Toast

A short message about something the user just did, in the corner of the screen: Changes saved, Link copied, Upload failed. It closes on its own after a few seconds. Mount one Toaster at the root of the app and call toast({ title }) from an event handler; a Toast element shown with state works too.

Preview

    Props

    • variant
    • duration
    • dismissible
    • open
    • title
    • description
    • action
    import { useState } from "react"
    import { Toast, Toaster } from "@/components/ui/toast"
    
    const [open, setOpen] = useState(true)
    
    <Toaster>
      <Toast open={open} onOpenChange={setOpen} title="Changes saved" description="Your project is up to date." />
    </Toaster>

    Usage

    When to use

    • Confirm an action the user just took, without stopping them: Changes saved, Link copied.
    • Offer a quick undo right after an action, when the same undo also exists elsewhere.

    When not to use

    • An error that blocks work. Show it in the page, next to what failed, for example with Field.
    • A question or a decision. Use AlertDialog.
    • A state that lasts, such as a failed build. Use Badge.

    Variants

    variant

    default has no icon. success, danger, warning and info add their status icon; the surface stays neutral.

      1. defaultdefault

        1. success

          1. danger

            1. warning

              1. info

              import { useState } from "react"
              import { Toast, Toaster } from "@/components/ui/toast"
              
              const [open, setOpen] = useState(true)
              
              <Toaster>
                <Toast open={open} onOpenChange={setOpen} title="Changes saved" description="Your project is up to date." />
              </Toaster>
              <Toaster>
                <Toast open={open} onOpenChange={setOpen} variant="success" title="Changes saved" description="Your project is up to date." />
              </Toaster>
              <Toaster>
                <Toast open={open} onOpenChange={setOpen} variant="danger" title="Changes saved" description="Your project is up to date." />
              </Toaster>
              <Toaster>
                <Toast open={open} onOpenChange={setOpen} variant="warning" title="Changes saved" description="Your project is up to date." />
              </Toaster>
              <Toaster>
                <Toast open={open} onOpenChange={setOpen} variant="info" title="Changes saved" description="Your project is up to date." />
              </Toaster>

              Examples

              Saved

              Shown with state here; in an app, call toast({ variant: "success", title: "Changes saved" }).

                import { useState } from "react"
                import { Toast, Toaster } from "@/components/ui/toast"
                
                const [open, setOpen] = useState(true)
                
                <Toaster>
                  <Toast open={open} onOpenChange={setOpen} variant="success" title="Changes saved" />
                </Toaster>

                With an action

                A longer duration, since the user has to reach the button. The action also lives in the History panel.

                  import { useState } from "react"
                  import { Toast, ToastAction, Toaster } from "@/components/ui/toast"
                  
                  const [open, setOpen] = useState(true)
                  
                  <Toaster>
                    <Toast open={open} onOpenChange={setOpen} title="Project archived" description="It is hidden from your project list." duration={8000} action={<ToastAction altText="Undo from the History panel" onClick={undo}>Undo</ToastAction>} />
                  </Toaster>

                  Failed

                    import { useState } from "react"
                    import { Toast, Toaster } from "@/components/ui/toast"
                    
                    const [open, setOpen] = useState(true)
                    
                    <Toaster>
                      <Toast open={open} onOpenChange={setOpen} variant="danger" title="Upload failed" description="The file is larger than 25 MB." />
                    </Toaster>

                    Info

                      import { useState } from "react"
                      import { Toast, Toaster } from "@/components/ui/toast"
                      
                      const [open, setOpen] = useState(true)
                      
                      <Toaster>
                        <Toast open={open} onOpenChange={setOpen} variant="info" title="Export started" description="The file downloads when it is ready." />
                      </Toaster>

                      Do and don't

                      Do

                      • Confirm an action the user just took: Changes saved, Link copied.
                      • Write the title in the past tense, and keep it to a few words.
                      • Mount one Toaster at the root of the app, and call toast() after the action is done.

                      Don't

                      • Don't put an error that blocks work in a toast; show it in the page, next to what failed.
                      • Don't use it for a question or a decision; use AlertDialog.
                      • Don't put the only way to do something in a toast action; it closes on its own.

                      Props

                      NameTypeValuesDefaultDescription
                      variantenumdefault | success | danger | warning | infodefaultdefault has no icon. success, danger, warning and info add their status icon; the surface stays neutral.
                      title requirednode--What happened, in a few words, past tense: Changes saved.
                      descriptionnode--One more sentence when the title is not enough.
                      durationnumber-4000How long it stays, in ms. Make it longer for a toast with an action or a long description.
                      actionnode--One ToastAction, such as Undo. Its altText says where else to do it.
                      dismissibleboolean-trueThe Dismiss button. Keep it, so a toast never sits over content the user needs.
                      openboolean--Set on Toast shown with state. Whether it is shown. Pair it with onOpenChange.
                      onOpenChangefunction--Set on Toast shown with state. Called with false when the time is up, or on Dismiss, Escape or a swipe.

                      Slots

                      NameRequiredDescription
                      toasteryesOne Toaster, mounted once at the root of the app.

                      Anatomy

                      PartDescription
                      rootToast: the raised surface with a border, radius-container and shadow-med, px-lg py-md, gap-md between its parts.
                      viewportToaster: the stack in the end corner at the bottom of the screen, 384px wide at most, gap-sm between toasts, p-lg from the edges.
                      iconThe status icon for success, danger, warning and info: Tabler icons, 16px, in the status text color, level with the title.
                      titleWhat happened: 14px medium primary text.
                      descriptionOptional second line: 13px secondary text.
                      actionToastAction: one small secondary Button, such as Undo.
                      closeThe Dismiss button: a 24px icon button with a Tabler X, 16px, secondary.
                      hitAreaTransparent ::before on the Dismiss button, never smaller than size-target-min.

                      Accessibility

                      Role: status

                      KeysAction
                      F8Moves focus to the toasts, so a keyboard user can reach an action or dismiss them.
                      TabMoves through the action and the Dismiss button of each toast.
                      EscapeCloses the focused toast.
                      • Every toast is announced politely, after what a screen reader is reading. It never takes focus.
                      • The timer pauses while the pointer is over a toast or focus is inside it, and while the window is in the background.
                      • A ToastAction needs altText: how to do the same without the toast (Undo from the History panel). A toast can close before anyone reaches it, so the action must also exist elsewhere.
                      • The status icon is decorative; the title says what happened, so the state never relies on color alone.
                      • It rises in only when the user allows motion, and fades in otherwise. It closes at once.

                      Install

                      npx shadcn add https://werewolf-ui.vercel.app/r/toast.json

                      This also adds styles/werewolf.css, the tokens every component uses, and any other component it needs. Import that file once in your root CSS, after @import "tailwindcss", with a path relative to that CSS file (from app/globals.css it is @import "../styles/werewolf.css").