v0.1.0

Notifications that morph beautifully

A notch-style toast system for Vue 3 and Nuxt with smooth morphing, promise states, and edge-attached or floating placement

npm i notch-toast-vue motion-v @vueuse/core

Examples

Click to preview

Toast types

Promise (morph animation)

Behavior checks

Promise examples morph from a loader into their final state. Every toast dismisses after the selected duration.

Builder

Position

Display mode

Animation preset

Fluid is the default. Gooey is intentionally expressive; smooth, subtle, and snappy refine the same motion system.

Title

Display duration8.0

Close button

Let people dismiss this toast with the cross button or the Escape key.

Generated code
<NotchToaster
  position="top-center"
  mode="attached"
  animation="fluid"
/>

toast.success("Toast rendered successfully", {
  duration: 8000,
  dismissible: false,
})
01

Vue 3

Install the package with its two peer dependencies, import the stylesheet once, and mount a single toaster near the root of your app.

Terminal
npm i notch-toast-vue motion-v @vueuse/core
App.vue
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.

TypeScript
import { toast } from 'notch-toast-vue'

toast.success('Payment of ₦50,000 sent')
toast.error('Transaction declined', { dismissible: true })
02

Nuxt

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.

nuxt.config.ts
export default defineNuxtConfig({
  modules: ['motion-v/nuxt', 'notch-toast-vue/nuxt'],
})
app.vue
// 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')
03

Documentation

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

PropTypeDefaultDescription
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

MethodDescription
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

OptionTypeDescription
idstringStable id, useful with toast.update and toast.dismiss.
durationnumberMilliseconds before auto-dismiss. 0 keeps it open.
dismissiblebooleanShows 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.

TypeScript
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.

TypeScript
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

TypeScript
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.