Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Success Toast Notification Block for React

The settings page of a form builder with its Save settings button: two success toasts are drawn on the page, and pressing Save raises a real toast through the block's own toaster, stacking up to three.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Tell people that a save worked, with this success toast for React with Base UI. It's the settings page of Formwren, a form and survey builder, drawn in greys inside a hairline frame with a plus mark on each corner: a top bar, a settings menu and three fields. The real Save settings Shine Button sits on the top bar, and at the foot end of the page two success toasts are drawn in place, newest last, each with an icon, a title, one line and a Dismiss button, wearing the look of the catalog's Toast. Press Save settings and the block raises a real toast through its own toaster: it appears at the end of the screen, in its own live region, and waits while the pointer or keyboard focus is on it. Press again and the toasts stack, three at most, the oldest leaving as the fourth arrives. It's built from Toast, Button, Shine Button and Guides, with CSS motion only. For settings pages, editors and any app where a quiet confirmation beats a dialog.

FAQ

Why are two toasts already on the page, and what do I keep?

So you can see a toast without pressing anything: on load the stack is drawn in place at the stage's foot end, using the catalog toast's own classes, newest last. Save settings raises a real toast and the drawn stack stays gone until a reload, as the invite dialog's in-place copy does. In your app keep the toaster and the raise call, and drop the drawn copy: the "in-place" state, DrawnToast and the ol in the frame.

How is the real toast raised on each library?

The block makes its own manager with createToaster() (Base UI's createToastManager), renders <Toaster toaster={toaster} /> once, and raises a toast with toaster.add({ id, type: "success", title, description, timeout }). Adding with the same id updates that toast in place; a timeout of 0 keeps it until it is closed.The block wraps the call in raise(note), so the rest of the file doesn't care which library is under it.

How long does a toast stay, and can it be held?

Six seconds when nothing holds it. Hovering a toast or moving keyboard focus onto it pauses the wait, and it resumes when you leave. Nothing here needs the toast to be seen in time: the status line and the page say the same thing, and a toast with an action never times out. Change STAY to make it longer or shorter.

Why only three at a time?

A toaster that keeps every toast turns a burst of saves into a wall. Each press raises a toast with its own id; when a fourth arrives the block takes the oldest away with its exit, so the toasts on screen are always the last three. The toaster's own limit is three too, so the two agree on every library.

Is it accessible?

The real toasts live in a live region that speaks each toast once and never takes focus, so Save settings keeps it. Every toast has a close button and, while one is on screen, Tab reaches the stack from the end of the page. The drawn copy is a list named "Notifications" with a Dismiss button per toast that names it, and a polite status message says what happened. The check icon is foreground, never a status color, and with reduced motion nothing slides.

What stays local?

Everything. Nothing is saved or sent: the settings are a drawing, the toasts are the only result, and the block says so in its status message. The copy is two constants at the top of the file (DRAWN and the note inside save); in your app, raise the toast from the response of your own save request, and raise an error toast when it fails.

How does it look on a phone?

The drawn toasts take the width of the page minus a margin and sit at the foot of the drawing; the settings menu drops out of the drawing so the form keeps its room. The real toast is the library's own: full width at the end of the screen on a phone.

  • Pro

    An invoicing app's list with a delete on every row: the toast says how many are deleted with an Undo, a second delete merges into the same toast and starts its wait again, and Restore deleted on the page does the same as Undo.

  • Pro

    A payments dashboard's charge page with a declined card: an error toast that never times out, a Retry that counts the attempts until the third turns it into Contact support, and the request id with a Copy button.

  • Pro

    Three reminders from a scheduling assistant as a deck of cards: Dismiss lets the next one come forward, Show all fans the deck into a list, and an empty deck says all caught up with a Reset.

  • Pro

    A visitor's message floating on a pricing page: a toggle group parks the card in any of four corners, Reply swaps its buttons for a one-line field, and Dismiss and Show again replay the slide-in.

  • Pro

    Real-Time Notification Feed

    Live and empty states

    A live status feed that doesn't jump: a typed script of six events starts when you press Start, new ones wait in a pill above the list, and pressing the pill lets them in at the top.

  • Pro

    An invoicing app's invoice with a Send button: one toast follows the request through the toaster's own promise call, Sending, then Invoice sent or Couldn't send with a Retry that succeeds, and a toggle group chooses how the next request ends.