01Vue 3
Install the package with its two peer dependencies, import the stylesheet once, and mount a single toaster near the root of your app.
npm i notch-toast-vue motion-v @vueuse/core
import { createApp } from 'vue'
import { NotchToaster } from 'notch-toast-vue'
import 'notch-toast-vue/style.css'
// App.vue template
<NotchToaster position="top-center" mode="attached" animation="fluid" />
Call toast from anywhere on the client. There is no provider or injection to set up.
import { toast } from 'notch-toast-vue'
toast.success('Payment of ₦50,000 sent')
toast.error('Transaction declined', { dismissible: true })
02Nuxt
Add the module alongside motion-v/nuxt. NotchToaster, toast and useNotchToast are auto-imported. Mount the toaster inside ClientOnly since toasts are client-side only.
export default defineNuxtConfig({
modules: ['motion-v/nuxt', 'notch-toast-vue/nuxt'],
})
// app.vue or layouts/default.vue — the component and toast are auto-imported
<ClientOnly>
<NotchToaster position="top-center" mode="attached" animation="fluid" />
</ClientOnly>
// anywhere on the client
toast.success('Saved')
03Documentation
One toast is visible at a time and the latest call wins. Updates to the active toast morph in place instead of stacking.
NotchToaster props
| Prop | Type | Default | Description |
|---|
position | 'top-center' | 'bottom-center' | 'top-center' | Which screen edge the toast anchors to. |
mode | 'attached' | 'floating' | 'attached' | Attached grows out of the edge as a notch. Floating is a standalone pill. |
animation | 'fluid' | 'gooey' | 'smooth' | 'subtle' | 'snappy' | 'fluid' | Motion preset for the shell and content morph. |
Toast methods
| Method | Description |
|---|
toast.show(title, opts?) | Default toast. Closes after 3.6s. |
toast.success(title, opts?) | Success toast. Closes after 3.6s. |
toast.info(title, opts?) | Info toast. Closes after 3.6s. |
toast.warning(title, opts?) | Warning toast. Persistent and dismissible. |
toast.error(title, opts?) | Error toast. Persistent, dismissible and announced assertively. |
toast.loading(title, opts?) | Loading toast with a spinner. Persistent until updated or dismissed. |
toast.promise(promise, msgs, opts?) | Shows loading, then morphs to success or error. Returns (and rethrows) the promise. |
toast.update(id, patch) | Patch the active toast in place. Ignored if that toast is no longer active. |
toast.dismiss(id?) | Dismiss the active toast, optionally only if it matches id. |
Options
| Option | Type | Description |
|---|
id | string | Stable id, useful with toast.update and toast.dismiss. |
duration | number | Milliseconds before auto-dismiss. 0 keeps it open. |
dismissible | boolean | Shows the close button and enables Escape to dismiss. |
action | { label: string; onClick: () => void } | Inline action button. |
Promises
Pass a promise and three messages. The toast shows a spinner, then morphs into success or error. The promise is returned and rethrown on failure, so you can still handle it.
await toast.promise(saveProfile(), {
loading: 'Saving changes...',
success: (data) => 'Profile updated',
error: (err) => err instanceof Error ? err.message : 'Something went wrong',
})
Updating in place
Keep the id returned by any toast method and patch it later. The shell resizes and the text slides to the new title.
const id = toast.loading('Processing KYC verification...')
// later — the same toast morphs in place
toast.update(id, { title: 'Identity verified', type: 'success', duration: 3600 })
Actions
toast.error('Payment failed — card declined', {
dismissible: true,
action: { label: 'Retry', onClick: () => retry() },
})
Accessibility
Toasts use role="status" with polite announcements; errors use role="alert" and are announced assertively. Dismissible toasts close with Esc unless focus is in an input. With prefers-reduced-motion, movement is replaced by a short fade.