Skip to Content

Toaster

The heart of the tactile experience. <Toaster /> manages your notification layer, bundling Sonner-compatible physics with a precision haptics engine. It’s the one package you need to bridge the gap between sight and touch. Migrating? See Migrate from Sonner.

Import styles once:

import 'web-haptics-toast/dist/styles.css';

Customization

You can see examples of most of the scenarios described below on the homepage.

Multiple Toasters

You can render multiple Toaster components with different ids and target toasts to each one:

<Toaster id="global" position="top-right" /> <Toaster id="canvas" position="bottom-left" /> <button onClick={() => `toast`('Global toast', { toasterId: 'global' })}> Show in Global Toaster </button> <button onClick={() => `toast`('Canvas toast', { toasterId: 'canvas' })}> Show in Canvas Toaster </button>

Expand

When you hover on one of the toasts, they will expand. You can make that the default behavior by setting the expand prop to true, and customize it even further with the visibleToasts prop.

// 9 toasts will be visible instead of the default, which is 3. <Toaster expand visibleToasts={9} />

Position

Changes the place where all toasts will be rendered.

// Available positions: // top-left, top-center, top-right, bottom-left, bottom-center, bottom-right <Toaster position="top-center" />

Styling all toasts

You can customize all toasts at once with toastOptions prop. These options will act as the default for all toasts.

<Toaster toastOptions={{ style: { background: 'red' }, className: 'my-toast', }} />

dir

Changes the directionality of the toast’s text.

// rtl, ltr, auto <Toaster dir="rtl" />

Custom ARIA label

You can customize the default ARIA label for the notification container and the toast close button.

// example in Finnish <Toaster containerAriaLabel="Ilmoitukset" toastOptions={{ closeButtonAriaLabel: 'Sulje' }} />

Haptics API

Haptics are on by default for toasts from this <Toaster />. For a single toast without vibration, pass haptics: false on that “toast() call (Toast). To fire patterns only from buttons or other handlers (not when every toast shows), use <Toaster haptics={false} /> and triggerHaptic — see Manual haptics.

Props are in the table below; full guide: Haptics.

API Reference

PropertyDescriptionDefault
idToaster instance id; use with toasterId on “toast().-
themeToast’s theme, either light, dark, or systemlight
richColorsTransforms toasts into high-intent signals using expressive, vibrant colors.false
expandToasts will be expanded by defaultfalse

| visibleToasts | Amount of visible toasts | 3 | | position | Place where the toasts will be rendered | bottom-right | | closeButton | Adds a close button to all toasts | false | | duration | Default toast lifetime in ms (per toast unless overridden). See toast(). | 4000 | | offset | Offset from the edges of the screen. | 32px | | mobileOffset | Offset from the left/right edges of the screen on screens with width smaller than 600px. | 16px | | dir | Directionality of toast’s text | ltr | | hotkey | Keyboard shortcut that will move focus to the toaster area. | ⌥/alt + T | | invert | Dark toasts in light mode and vice versa. | false | | toastOptions | Default options for all toasts. See toast() for fields (className, duration, …). | - | | gap | Gap between toasts when expanded | 14 | | haptics | Enable haptic feedback for toasts (vibration or debug sound). | true | | hapticPatternMap | Map toast types to preset names: success, error, light, nudge, buzz, etc. | built-in | | hapticsDebug | On desktop, play patterns as sound when vibration is not available. | false | | hapticsShowSwitch | Built-in on-screen haptics toggle for end users (engine showSwitch). | false | | icons | Override default toast icons (success, error, loading, …). | - | | containerAriaLabel | Accessible name for the toast region. | Notifications | | customAriaLabel | If set, used as the region aria-label instead of the default pattern. | - | | system | Feature flags: dedupe, dismissReason for dedupeKey / onClose reasons. | - | | className | CSS class on the toaster root. | - | | style | Inline styles on the toaster root. | - |

System (production behaviors)

The system prop centralizes production-grade behaviors that may change toast semantics. These are OFF by default to avoid breaking existing app flows.

Dedupe

When enabled, calling toast.*(..., { dedupeKey: 'some-key' }) will update the existing toast with the same dedupeKey instead of creating a new one.

<Toaster system={{ dedupe: { enabled: true }, }} />

Dismiss Reason (onClose)

When enabled, toasts created with onClose will receive a dismissal reason. This is useful for analytics/debug so you can distinguish timeout vs swipe vs close vs action.

<Toaster system={{ dismissReason: { enabled: true }, }} />
Last updated on