Skip to content

useToast, toast.promise & toast.undo

useToast

The main composable. Returns a ToastApi object. Works inside and outside Vue components.

ts
const toast = useToast(context?: ToastContext): ToastApi

When called without arguments inside a component, it uses the injected context (set up by the plugin). When called outside a component it falls back to the global singleton. Pass a ToastContext from createToastContext() to use an isolated queue.

Methods

MethodSignatureDescription
toast()(message, options?) → idShow an info toast
toast.success()(message, options?) → idShow a success toast
toast.error()(message, options?) → idShow an error toast (priority: high by default)
toast.warning()(message, options?) → idShow a warning toast
toast.info()(message, options?) → idShow an info toast
toast.loading()(message, options?) → idShow a loading toast (no auto-dismiss, not closable by default)
toast.custom()(component, options?) → idReplace the toast body with a Vue component
toast.promise()(promise, messages, options?) → PromiseSee toast.promise
toast.undo()(message, options) → idSee toast.undo
toast.update()(id, partial) → voidMerge options (and optionally the message) into an existing toast
toast.updateMessage()(id, message) → voidUpdate only the message text without touching options
toast.dismiss()(id?) → voidClose a toast by id; omit id to close all
toast.dismissAll()(position?) → voidClose all toasts, optionally filtered by position
toast.isActive()(id) → booleanCheck if a toast is still visible
toast.pauseAll()() → voidPause all timers
toast.resumeAll()() → voidResume all timers

ToastOptions

OptionTypeDefaultDescription
idstringautoUnique id; if the same id is already active the toast is updated
typeToastType'info'Visual style; one of info / success / warning / error / loading / custom
priorityToastPriority'normal'Queue priority; one of critical / high / normal / low
durationnumber4000Auto-dismiss delay in ms; 0 = sticky (never auto-closes)
positionToastPositioncontainer defaultRender this toast at a specific position, regardless of the container's position prop
closablebooleantrueShow the close button
groupKeystringGroup toasts with the same key into a stack
iconComponent | string | falsetype defaultSVG component, emoji string, or false to hide
action{ label, onClick }Extra action button inside the toast
undo{ label?, onUndo, duration? }Undo button with timer; see toast.undo
onClose() => voidCalled when the toast is closed (any reason)
onAutoClose() => voidCalled only when the timer expires
pauseOnHoverbooleantruePause the timer on mouse enter
pauseOnFocusLossbooleantruePause the timer when the tab goes to background
swipeToDismissbooleantrueEnable swipe left / right to dismiss on touch devices
persistbooleanfalseRestore from localStorage after reload (only for toasts without callbacks)
componentComponentReplace the entire toast body with a Vue component
componentPropsRecord<string, unknown>Props forwarded to component
ariaLive'assertive' | 'polite'autoOverride the automatic aria-live value
theme'light' | 'dark' | 'system' | ToastDesignTokensPer-toast theme or token overrides

Examples

All toast types:

ts
toast.info('Sync complete')
toast.success('File uploaded')
toast.warning('Disk almost full (92 %)')
toast.error('Connection refused')
toast.loading('Fetching data…')

Custom duration and position:

ts
toast.success('Copied to clipboard', {
  duration: 2000,
  position: 'top-center',
})

With an action button:

ts
toast.info('New message from Alex', {
  action: {
    label: 'Open',
    onClick: () => router.push('/messages'),
  },
})

Emoji icon:

ts
toast.success('Backup complete', { icon: '💾' })

Sticky until manually dismissed:

ts
const id = toast.error('Server is down', { duration: 0, closable: true })
// Later:
toast.dismiss(id)

Update an existing toast:

ts
const id = toast.loading('Uploading…')
// Update message only (no option changes):
toast.updateMessage(id, 'Processing…')
// Or update message + options together:
toast.update(id, { message: 'Almost done…', duration: 3000 })

Rich content via Vue component:

ts
import RichCard from './RichCard.vue'

toast.custom(RichCard, {
  componentProps: { title: 'Hello', body: 'World' },
  duration: 0,
  closable: true,
})

toast.promise

Automatically switches a loading toast to success or error based on the promise result. Returns the original promise so you can await it.

ts
toast.promise<T>(
  promise: Promise<T>,
  messages: PromiseToastMessages<T>,
  options?: ToastOptions,
): Promise<T>

PromiseToastMessages

FieldTypeDescription
loadingstringMessage while the promise is pending
successstring | (data: T) => stringMessage on resolve; receives the resolved value
errorstring | (err: unknown) => stringMessage on reject; receives the error

Examples

Static messages:

ts
await toast.promise(
  fetch('/api/deploy').then((r) => r.json()),
  {
    loading: 'Deploying…',
    success: 'Deployed successfully!',
    error: 'Deployment failed',
  },
)

Dynamic messages from data / error:

ts
const user = await toast.promise(fetchUser(id), {
  loading: 'Loading user…',
  success: (u) => `Welcome, ${u.name}!`,
  error: (e) => `Could not load user: ${(e as Error).message}`,
})

In a Pinia action:

ts
// stores/files.ts
import { toast } from 'vue-toast-kit'

export const useFileStore = defineStore('files', {
  actions: {
    async upload(file: File) {
      return toast.promise(uploadAPI(file), {
        loading: `Uploading ${file.name}…`,
        success: (res) => `${res.name} uploaded (${res.size} KB)`,
        error: (e) => `Upload failed: ${(e as Error).message}`,
      })
    },
  },
})

The promise reject is re-thrown after updating the toast, so your try / catch or .catch() still fires normally.

toast.undo

Creates a toast with a countdown progress bar. When the user clicks the undo button, onUndo() is called and the toast closes immediately. When the timer runs out, the toast closes silently (action confirmed).

ts
toast.undo(message: string, options: ToastOptions & {
  undo: {
    onUndo: () => void | Promise<void>
    label?:   string   // default: 'Отменить'
    duration?: number  // ms, default: 5000
  }
}): string

Examples

Delete with undo:

ts
function deleteFile(id: string) {
  markForDeletion(id)

  toast.undo(`File "${fileName}" deleted`, {
    undo: {
      label: 'Restore',
      duration: 6000,
      onUndo: () => {
        restoreFile(id)
        toast.success('File restored')
      },
    },
    onAutoClose: () => permanentlyDelete(id),
  })
}

Archive email:

ts
toast.undo('Email archived', {
  icon: '📨',
  undo: {
    onUndo: () => moveToInbox(emailId),
  },
})

Async undo:

ts
toast.undo('Record deleted', {
  undo: {
    onUndo: async () => {
      await api.restore(recordId)
      toast.success('Record restored!')
    },
  },
})