Skip to content

Toaster

Toast notifications: brief, temporary messages anchored to the edge of the screen. Auto-dismiss on a timer; pause on hover; manually dismissable. Built on vue-sonner.

ts
const { toast } = useToast()
toast.success({ title: 'Saved', description: 'Your changes are live.' })
toast.error({ title: 'Sync failed', description: 'Something went wrong.' })

Toasts are non-blocking — they confirm or report something happened without interrupting the workflow. If the user has to make a decision, that's a Modal. If the message needs to stay visible until resolved, that's a Banner.

useToast() is a global singleton (created with @vueuse/core's createGlobalState) — calling it anywhere returns the same toast function.

When to fire a toast

  • System feedback — confirm a background action completed (file saved, export ready, settings updated)
  • Async operations — notify when a long-running task finishes without forcing the user to watch it
  • Transient alerts — surface info that doesn't require any action

When not to fire a toast

  • Critical errors that need a decision — use a Modal or inline error
  • Persistent information the user needs to refer back to — toasts auto-dismiss; put it in the UI instead
  • Stacking many notifications — keep simultaneous toasts to ~3. If many fire at once (bulk operations), summarise into one toast.

Writing toast copy

  • Keep it short — aim for ~10 words. "3 buildings updated." beats "The bulk update operation has completed and 3 buildings were updated successfully."
  • Confirm what happened, in past tense. "Report exported." not "Exporting…".
  • Sentence case, never all caps. No alarmist language — that's what a Modal is for.
  • For errors, add brief remediation in the description. "Export failed." → "Check your connection and try again."

Variant durations

VariantDurationUse for
successAuto-dismiss (3 s)Confirmation of an action that completed
info / defaultAuto-dismiss (4 s)Neutral feedback, async progress
warningAuto-dismiss (5 s)Non-blocking concern the user should notice
errorPersistentFailure the user should read and dismiss
missingPersistentRequired data is absent

Errors and missing-info stay until dismissed — the user shouldn't miss them while reaching for the mouse.

Setup

Mount <Toaster /> once at the app root.

html
<Toaster />
ts
import { Toaster } from '@scaler-tech/aurora/toaster'

Fire a toast

ts
import { useToast } from '@scaler-tech/aurora/toaster'

const { toast } = useToast()

toast({
    variant: 'success',
    title: 'Saved',
    description: 'Your changes are live.',
})

// or, equivalently, via the variant shorthand:
toast.success({
    title: 'Saved',
    description: 'Your changes are live.',
})

toast.success, toast.error, toast.warning, toast.info, and toast.missing are convenience methods that pre-fill variant. Each accepts either a string (used as description) or an options object.

Variants

ts
toast({ variant: 'success', title: 'Saved', description: 'Your changes are live.' })
toast({ variant: 'error', title: 'Sync failed', description: 'Something went wrong.' })
toast({ variant: 'warning', title: 'Warning', description: 'Please review your input.' })
toast({ variant: 'info', title: 'Heads up', description: 'A new feature is available.' })
toast({ variant: 'missing', title: 'Missing data', description: 'Some required info is missing.' })

Persistent toast (duration: 0)

Pass duration: 0 for a toast that doesn't auto-dismiss. The user closes it via the close button.

ts
toast({
    variant: 'warning',
    title: 'Persistent toast',
    description: 'This toast will not auto-dismiss. Click the X to close.',
    duration: 0,
})

Hover to pause

Auto-dismiss timers pause while the user hovers over a toast. Resume on mouseleave. Built into vue-sonner — no config needed.

Re-fire the same toast (replace by id)

Pass an id. Calling again with the same id dismisses the previous toast (with its close animation), then shows the new one. Toasts without an id always stack.

Click the first button repeatedly — each new toast replaces the previous. Click the second button repeatedly — they stack.

ts
toast({
    id: 'toast-with-id',
    title: 'Toast with id',
    description: 'This toast has an identifier and will replace the old one',
})

toast({
    title: 'Regular toast',
    description: 'This toast has no identifier and will stack up',
})

Useful for status updates where the same conceptual message ("Calculating…", "Synced") fires from multiple code paths.

Action button

Add a trailing action button. The toast stays open until the user clicks the action or the close button (or until duration elapses).

ts
toast.info({
    title: 'Saved',
    description: 'Used data has been updated',
    duration: 5000,
    closeButton: false,
    action: {
        label: 'Undo',
        onClick: () => { /* … */ },
    },
})

Without rich colors

By default, toasts use a tinted background that matches the variant. Pass richColors: false for a neutral white background with only the variant border + icon.

ts
toast({
    variant: 'success',
    title: 'Subtle toast',
    description: 'No tinted background',
    richColors: false,
})

Burst behavior

When toasts fire in rapid succession (within 300ms of each other), useToast adds a 50ms delay between consecutive toasts so they cascade in instead of stacking on top of each other. Single toasts fire with no delay.

ts
for (let i = 1; i <= 5; i++) {
    toast({ variant: 'success', title: `Toast ${i}`, description: `Number ${i}` })
}

Toaster — Props

PropTypeDefaultDescription
position'top-left' | 'top-right' | 'top-center' | 'bottom-left' | 'bottom-right' | 'bottom-center''top-right'Anchor for the toast stack.
offset{ top?: number; right?: number; bottom?: number; left?: number }Pixel offsets from the chosen anchor.

The component renders up to 5 visible toasts at once with an 8px gap between them.

toast options

FieldTypeDefaultDescription
variant'success' | 'error' | 'warning' | 'info' | 'missing''info'Semantic color and matching icon.
titlestring | VNodeBold first line.
descriptionstringBody text below the title.
durationnumber3000Ms before auto-dismiss. 0 keeps the toast until manually dismissed.
richColorsbooleantrueTinted background + matching variant border. false = neutral white background.
closeButtonbooleantrueShow the trailing close (X) button.
action{ label: string; onClick: () => void }Trailing action button.
idstring | numberautoStable id — re-using one updates the existing toast in place.

Other vue-sonner ExternalToast options (onDismiss, onAutoClose, cancel, position, etc.) are forwarded through.

Variant map

VariantIcon
successcheck-circle (success-core color)
errorexclamation-circle (error-core)
warningminus-circle (warning-core)
missingexclamation-circle (missing-core)
infoinformation-circle (cta)