useToast, toast.promise & toast.undo
useToast
The main composable. Returns a ToastApi object. Works inside and outside Vue components.
const toast = useToast(context?: ToastContext): ToastApiWhen 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
| Method | Signature | Description |
|---|---|---|
toast() | (message, options?) → id | Show an info toast |
toast.success() | (message, options?) → id | Show a success toast |
toast.error() | (message, options?) → id | Show an error toast (priority: high by default) |
toast.warning() | (message, options?) → id | Show a warning toast |
toast.info() | (message, options?) → id | Show an info toast |
toast.loading() | (message, options?) → id | Show a loading toast (no auto-dismiss, not closable by default) |
toast.custom() | (component, options?) → id | Replace the toast body with a Vue component |
toast.promise() | (promise, messages, options?) → Promise | See toast.promise |
toast.undo() | (message, options) → id | See toast.undo |
toast.update() | (id, partial) → void | Merge options (and optionally the message) into an existing toast |
toast.updateMessage() | (id, message) → void | Update only the message text without touching options |
toast.dismiss() | (id?) → void | Close a toast by id; omit id to close all |
toast.dismissAll() | (position?) → void | Close all toasts, optionally filtered by position |
toast.isActive() | (id) → boolean | Check if a toast is still visible |
toast.pauseAll() | () → void | Pause all timers |
toast.resumeAll() | () → void | Resume all timers |
ToastOptions
| Option | Type | Default | Description |
|---|---|---|---|
id | string | auto | Unique id; if the same id is already active the toast is updated |
type | ToastType | 'info' | Visual style; one of info / success / warning / error / loading / custom |
priority | ToastPriority | 'normal' | Queue priority; one of critical / high / normal / low |
duration | number | 4000 | Auto-dismiss delay in ms; 0 = sticky (never auto-closes) |
position | ToastPosition | container default | Render this toast at a specific position, regardless of the container's position prop |
closable | boolean | true | Show the close button |
groupKey | string | — | Group toasts with the same key into a stack |
icon | Component | string | false | type default | SVG 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 | () => void | — | Called when the toast is closed (any reason) |
onAutoClose | () => void | — | Called only when the timer expires |
pauseOnHover | boolean | true | Pause the timer on mouse enter |
pauseOnFocusLoss | boolean | true | Pause the timer when the tab goes to background |
swipeToDismiss | boolean | true | Enable swipe left / right to dismiss on touch devices |
persist | boolean | false | Restore from localStorage after reload (only for toasts without callbacks) |
component | Component | — | Replace the entire toast body with a Vue component |
componentProps | Record<string, unknown> | — | Props forwarded to component |
ariaLive | 'assertive' | 'polite' | auto | Override the automatic aria-live value |
theme | 'light' | 'dark' | 'system' | ToastDesignTokens | — | Per-toast theme or token overrides |
Examples
All toast types:
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:
toast.success('Copied to clipboard', {
duration: 2000,
position: 'top-center',
})With an action button:
toast.info('New message from Alex', {
action: {
label: 'Open',
onClick: () => router.push('/messages'),
},
})Emoji icon:
toast.success('Backup complete', { icon: '💾' })Sticky until manually dismissed:
const id = toast.error('Server is down', { duration: 0, closable: true })
// Later:
toast.dismiss(id)Update an existing toast:
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:
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.
toast.promise<T>(
promise: Promise<T>,
messages: PromiseToastMessages<T>,
options?: ToastOptions,
): Promise<T>PromiseToastMessages
| Field | Type | Description |
|---|---|---|
loading | string | Message while the promise is pending |
success | string | (data: T) => string | Message on resolve; receives the resolved value |
error | string | (err: unknown) => string | Message on reject; receives the error |
Examples
Static messages:
await toast.promise(
fetch('/api/deploy').then((r) => r.json()),
{
loading: 'Deploying…',
success: 'Deployed successfully!',
error: 'Deployment failed',
},
)Dynamic messages from data / error:
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:
// 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).
toast.undo(message: string, options: ToastOptions & {
undo: {
onUndo: () => void | Promise<void>
label?: string // default: 'Отменить'
duration?: number // ms, default: 5000
}
}): stringExamples
Delete with undo:
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:
toast.undo('Email archived', {
icon: '📨',
undo: {
onUndo: () => moveToInbox(emailId),
},
})Async undo:
toast.undo('Record deleted', {
undo: {
onUndo: async () => {
await api.restore(recordId)
toast.success('Record restored!')
},
},
})