Toast

A brief notification that gives feedback about an action or event.
vue
<script setup lang="ts">
import { ref } from 'vue'
import { toast, Button } from '@typlog/ui'

const count = ref(0)

const onClick = () => {
  count.value += 1
  toast(`You have received ${count.value} events.`)
}
</script>

<template>
  <Button @click="onClick">Click me!</Button>
</template>

Provider ​

To use the toast module, you need to set up the ToastProvider first. Simply place it within the ThemeProvider – its position doesn't matter, and it will function as expected.

vue
<script setup>
  import { ThemeProvider, ToastProvider } from '@typlog/ui'
</script>
<template>
  <ThemeProvider>
    <ToastProvider />
  </ThemeProvider>
</template>
PropDefaultType
breakpoint640
number

The viewport width in pixels at which toast messages switch to a full-width mobile layout.

manager
–
Enum

An isolated toast manager. Defaults to the manager used by the global toast function.

position"bottom-right"
Enum
size"1"
"1""2""3"

Isolated applications and SSR ​

The exported toast function and a provider without a manager prop use a shared default queue. This preserves the convenient setup for a single client-side application.

For server-side rendering or pages containing multiple Vue applications, create one manager for each app or request. Pass it to the provider and use the manager's toast function so messages cannot leak between queues:

vue
<script setup>
  import { createToastManager, ToastProvider } from '@typlog/ui'

  const toastManager = createToastManager()
  const toast = toastManager.toast
</script>

<template>
  <ToastProvider :manager="toastManager" />
  <button @click="toast.success('Saved')">Save</button>
</template>

In an SSR application, create the manager inside the per-request app factory, not at module scope.

Responsive layout ​

Toast messages use a full-width layout with a var(--space-4) gutter on both sides when the viewport is narrower than 640px by default. The top or bottom position is preserved, while the desktop left, center, or right alignment is replaced by the shared mobile layout. When swipeDirection is omitted, top toasts swipe up and bottom toasts swipe down on narrow viewports; an explicit direction always takes precedence.

Set breakpoint to change the viewport width at which this behavior starts:

vue
<ToastProvider :breakpoint="768" />
vue
<script setup lang="ts">
import { toast, Button } from '@typlog/ui'

const showToast = () => {
  toast({
    title: 'Responsive toast',
    description: 'Resize the browser below the provider breakpoint to see the full-width layout.',
  })
}
</script>

<template>
  <Button @click="showToast">Show responsive toast</Button>
</template>

Position ​

You can customize the position of toast messages using the position prop on ToastProvider. By default, toasts appear in the bottom-right corner.

<ToastProvider
  position="bottom-right"
/>

Size ​

You can customize the size of toast messages using one of the three available size options.

<ToastProvider
  size="1"
/>

Examples ​

Methods ​

Promise ​

vue
<script setup lang="ts">
import { toast, Button } from '@typlog/ui'

const successFn = () => new Promise((resolve) => setTimeout(resolve, 2000))
const errorFn = () => new Promise((_, reject) => setTimeout(reject, 2000))

const onClickSuccess = () => {
  toast.promise(successFn, {
    loading: 'Fetching data ....',
    success: () => {
      return 'You have a new message.'
    },
  })
}

const onClickError = () => {
  toast.promise(errorFn, {
    loading: 'Fetching data ....',
    success: () => {
      return 'You have a new message.'
    },
    error: () => {
      return 'You have a new error.'
    },
  })
}
</script>

<template>
  <div class="flex items-center gap-4">
    <Button variant="soft" @click="onClickSuccess">With success</Button>
    <Button color="red" variant="soft" @click="onClickError">With error</Button>
  </div>
</template>

Description ​

vue
<script setup lang="ts">
import { toast, Button } from '@typlog/ui'

const onClick = () => {
  const now = new Date().toLocaleDateString('en-US', {
    year: 'numeric',
    month: 'long',
    day: '2-digit',
    weekday: 'short',
    hour: '2-digit',
    minute: '2-digit',
  })
  toast({
    title: 'A new event with description.',
    description: now,
  })
}
</script>

<template>
  <Button @click="onClick">Description</Button>
</template>
Last updated Sep 15, 2026