nori-ui

Toast

Imperative notification system based on sonner — auto-dismiss, stacking, six positions, and a typed action slot.

838 Bgzipped

At a glance

  • Mount <Toaster /> exactly once near your app root, then call the imperative toast(...) from anywhere.
  • Tone-specific shortcuts: toast.success, toast.error, toast.warning, toast.info, plus toast.dismiss(id?) and toast.promise(...).
  • Web: powered by sonner — full feature set including swipe-to-dismiss, screen-reader live region, and rich colors.
  • Native: matched API surface with the same six positions, swipe-to-dismiss, auto-dismiss, and stacking. No if (Platform.OS === 'web') in your code.
  • Six positions: top-left, top-center (default), top-right, bottom-left, bottom-center, bottom-right. The global anchor lives on <Toaster position>; any individual call may override with toast(msg, { position }).
  • duration defaults to 4000ms. Pass Infinity to keep a toast open until dismissed manually.

Mount the Toaster once

// app/layout.tsx (Next.js) — or your tree root
import { Toaster } from '@nori-ui/core/client';
 
export default function Layout({ children }) {
  return (
    <>
      {children}
      <Toaster richColors />
    </>
  );
}

The docs site mounts a single <Toaster richColors /> at the root — that's why every demo on this page uses the saturated tone surface. richColors is a Toaster-level flag, not a per-call option.

Tones, action, promise

All five tones plus an inline action button and toast.promise for async flows. Click "Promise" and watch the same card swap from the loading state to success after 1.5s.

Direction:
Locale:

Per-call position override

The global <Toaster position> sets the default anchor; any single call can override it with toast(msg, { position: 'bottom-right' }). Useful for one-off toasts that belong somewhere different from the rest of your UI.

Direction:
Locale:

Update an existing toast in place

Reuse the same id to swap a loading toast for a success/error one without spawning a second card. Useful when toast.promise doesn't fit the flow — chained calls, intermediate progress states, or backend events that arrive asynchronously.

Direction:
Locale:

API

toast(title, options?) // generic
toast.success(title, options?)
toast.error(title, options?)
toast.warning(title, options?)
toast.info(title, options?)
toast.message(title, options?)  // alias for the default tone
toast.dismiss(id?)              // dismiss specific or all
toast.promise(p, { loading, success, error })

options accepts description, duration, action, cancel, tone, id, position, icon, className. Each call returns the toast's id — pass it to toast.dismiss(id) later or to toast(title, { id }) to update the existing entry.

<Toaster> props

The mount point is configured once near your app root. The most common knobs:

  • position — global default anchor.
  • expand — keep stacked toasts visible at full size instead of collapsing them. Default false.
  • gap — vertical gap between stacked toasts in pixels. Default 14.
  • offset — distance from the chosen edge of the screen. Accepts a number (px) or a CSS string. Default 16.
  • visibleToasts — maximum number of toasts shown at once. Older ones queue and pop in as space frees up. Default 3.
  • closeButton — render a small ✕ on every toast. Default false. Per-call swipe-to-dismiss still works either way.
  • richColors — saturated tone surfaces (used on this docs site). Default false.
<Toaster
    position="bottom-right"
    expand
    gap={8}
    offset={24}
    visibleToasts={5}
    closeButton
/>

Props

PropTypeDefaultDescription
closeButtonbooleanShow a small close button in the top-right corner of each toast. @defaultValue false
durationnumberDefault duration in ms for toasts that don't pass their own. @defaultValue 4000
expandbooleanWeb only: expand the stack on hover (sonner's `expand`). Native always renders the visible toasts uncollapsed, so this is a no-op there. @defaultValue false
gapnumberSpacing between stacked toasts in px. @defaultValue 14
offsetnumberPad the toaster away from the viewport edges by this many px. @defaultValue 24
positionenumWhere the toast stack anchors. @defaultValue 'top-center'
richColorsbooleanWeb only: full-color toasts per tone (sonner's `richColors`). On native this is honored visually too, with the same palette recipe. @defaultValue false
visibleToastsnumberMaximum number of toasts visible at once. Older toasts collapse behind newer ones (web) or pop off the top of the stack (native). @defaultValue 3

On this page

Preview theme