Skip to content

Toast

Show brief notifications with swipe dismissal, triggered from anywhere in your app.

import { PromiseOptions, Toaster, ToastOptions } from '@youj/react'

Installation & usage

npm i @youj/react

import { PromiseOptions, Toaster, ToastOptions } from '@youj/react'

For an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.

Use Toast to confirm an action or report a background task’s result, such as a copied link or completed deploy. Toasts dismiss automatically. Put essential information in an Alert, or use an Alert Dialog when you need a response. Avoid repeating feedback already visible on the page.

In the Next.js App Router, render this from a Client Component, a file that starts with 'use client': a toast's action.onClick is a function, and toast() runs from event handlers, which a Server Component can't have. Server rendering has the rest.

Render one Toaster near the root of the app, inside YoujProvider so toasts follow its Speed and reduced-motion settings. Then call toast() from anywhere: event handlers, data hooks, code outside React.

app/layout.tsx
import { basalt, YoujProvider, themeProps } from '@youj/core'
import { ThemeScript, Toaster } from '@youj/react'
import './globals.css'

// The layout from Installation, with a Toaster added: keep its font lines and the className on <html>.
export default function RootLayout({ children }: LayoutProps<'/'>) {
  return (
    <html lang="en" suppressHydrationWarning {...themeProps(basalt)}>
      <head>
        <ThemeScript />
      </head>
      <body>
        <YoujProvider theme={basalt}>
          {children}
          <Toaster />
        </YoujProvider>
      </body>
    </html>
  )
}
import { toast } from '@youj/react'

toast.success('Invite link copied', { description: 'Anyone at Acme with the link can join orion.' })

toast() and its typed helpers return the toast's id. Only one Toaster renders at a time. If a second one mounts, for example in a layout and again in a page, it shows nothing until the first unmounts, so each toast appears and is announced once. On this page, the Toaster in the demo renders the toasts from every preview, so its Speed and Reduced motion controls apply to all of them.

Reference

Propsposition, limit, timeout… (5)

Props

Toaster

Toaster props
PropType
positionToasterPosition
'top-start''top-center''top-end''bottom-start''bottom-center''bottom-end'

The corner or edge the stack grows from; start and end follow the writing direction.

default 'bottom-end'

'bottom-end'
limitnumber

How many toasts show at once; older ones wait, hidden.

default 3

3
timeoutnumber

Default 5000.

default 5000

5000
classNamestring–
soundboolean

With sound on (YoujProvider’s sound), toasts sound as they arrive. false keeps them silent.

default true

true

timeout is the default time on screen, in milliseconds, for every toast. 0 keeps toasts until they're dismissed.

toast()

CallReturnsDoes
toast(title, options?)the idShows a plain toast.
toast.success(title, options?)the idAdds a success icon. toast.info, toast.warning and toast.error work the same way.
toast.promise(work, steps)a promiseShows steps.loading until work settles, then steps.success or steps.error.
toast.update(id, changes)nothingChanges the title or any option of a toast in place.
toast.dismiss(id?)nothingCloses one toast, or every toast when called without an id.

Options

Every toast call takes these, and so does each step of toast.promise. A step can also be a plain string, which becomes its title.

OptionTypeDefaultDoes
idstringgeneratedNames the toast. A call with an existing id updates that toast in place and restarts its timer.
descriptionReactNodeThe second line.
timeoutnumberthe Toaster'sTime on screen in milliseconds. 0 keeps it until it's dismissed.
priority'low' or 'high''low''high' interrupts: the toast is announced assertively, through an alert.
action{ label, onClick }A button in the toast. Pressing it runs onClick and dismisses the toast.
mediaReactNodeA visual at the toast's start in place of the status icon: an illustration, a loader or an animated icon. Decorative, so the title still carries the message.
onClose() => voidCalled when the toast starts to close.
onRemove() => voidCalled once it has left and is removed.
MotionEnter, stack and spread, height… · reduced motion

Motion

Motion tokens
MomentTokens
Enterrises in from beyond the edge (yj-toast)
duration.slowease.enter

340ms · cubic-bezier(0.16, 1, 0.3, 1)

340mscubic-bezier(0.16, 1, 0.3, 1)
Stack and spreadthe toasts behind step back, or spread out on hover
duration.slowease.enter

340ms · cubic-bezier(0.16, 1, 0.3, 1)

340mscubic-bezier(0.16, 1, 0.3, 1)
Heightthe stack fits the front toast
duration.fastease.standard

140ms · cubic-bezier(0.2, 0, 0, 1)

140mscubic-bezier(0.2, 0, 0, 1)
Text behindfades out behind the front toast (yj-toast-content)
duration.baseease.standard

220ms · cubic-bezier(0.2, 0, 0, 1)

220mscubic-bezier(0.2, 0, 0, 1)
Exitback past the edge as it fades, or on in the swipe direction
duration.slowease.enter

340ms · cubic-bezier(0.16, 1, 0.3, 1)

340mscubic-bezier(0.16, 1, 0.3, 1)
Promise headlinespinner to check or cross, with the width
spring.snappy

0.2s, bounce 0

0.2s, bounce 0
Media landsthe stage grows in just after the toast
spring.settle

0.45s, bounce 0.3

0.45s, bounce 0.3
Media changesthe new media fades and grows in over the old
duration.slowease.enter

340ms · cubic-bezier(0.16, 1, 0.3, 1)

340mscubic-bezier(0.16, 1, 0.3, 1)
Error shake4, 3 and 2px, then home
duration.slowease.standard

340ms · cubic-bezier(0.2, 0, 0, 1)

340mscubic-bezier(0.2, 0, 0, 1)

Reduced motion

Toasts appear and leave in place, and the stack changes shape at once. A swipe still tracks the finger. Status icons appear already drawn, a pending promise toast shows its title without a spinner, and media appears and changes in place. A loader in the media shows its still frame.

Reduced motion

Toasts appear and leave in place, with no rise, slide or fade, and the stack collapses and spreads without moving. A swipe still moves the toast under the finger, because that motion is the person's own. Status icons hold their drawn pose, and a promise toast swaps its line without a morph or a shake.

AccessibilityKeyboard, focus, announcements

Accessibility

  • The Toaster is a polite live region named "Notifications". New toasts, and the steps of a promise toast, are announced without moving focus.
  • priority: 'high' makes a toast interrupt. Base UI speaks it through an assertive alert and hides the toast itself from assistive technology until it's focused. Keep it for the rare toast that can't wait.
  • F6 moves focus to the notifications and pauses their timers, and Shift+Tab from there goes back to where you were. Each toast is a tab stop, its buttons follow it, and Escape dismisses the focused toast.
  • Timers pause while the stack is hovered or focused, and while the window is in the background, so a toast doesn't disappear while someone reads it.
  • media is hidden from assistive technology, along with its status badge. The title and description carry the message, and a toast's type is announced the same way with or without media.
  • The × button, named "Dismiss", shows once the stack is spread, like the rest of the stack's controls. Toasts past the limit are hidden and inert until there's room.