Usage
Use the useToast composable to display a toast in your application.
App component which uses our Toaster component which uses the ToastProvider component from Reka UI.Title
Pass a title field to the toast.add method to display a title.
<script setup lang="ts">
const props = defineProps<{
  title: string
}>()
const toast = useToast()
function showToast() {
  toast.add(props)
}
</script>
<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>
Description
Pass a description field to the toast.add method to display a description.
<script setup lang="ts">
const props = defineProps<{
  title: string
  description: string
}>()
const toast = useToast()
function showToast() {
  toast.add(props)
}
</script>
<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>
Icon
Pass an icon field to the toast.add method to display an Icon.
<script setup lang="ts">
const props = defineProps<{
  icon: string
}>()
const toast = useToast()
function showToast() {
  toast.add({
    title: 'Uh oh! Something went wrong.',
    description: 'There was a problem with your request.',
    icon: props.icon
  })
}
</script>
<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>
Avatar
Pass an avatar field to the toast.add method to display an Avatar.
<script setup lang="ts">
import type { AvatarProps } from '@nuxt/ui'
const props = defineProps<{
  avatar: AvatarProps
}>()
const toast = useToast()
function showToast() {
  toast.add({
    title: 'User invited',
    description: 'benjamincanac was invited to the team.',
    avatar: props.avatar
  })
}
</script>
<template>
  <UButton label="Invite user" color="neutral" variant="outline" @click="showToast" />
</template>
Color
Pass a color field to the toast.add method to change the color of the Toast.
<script setup lang="ts">
import type { ToastProps } from '@nuxt/ui'
const props = defineProps<{
  color: ToastProps['color']
}>()
const toast = useToast()
function showToast() {
  toast.add({
    title: 'Uh oh! Something went wrong.',
    description: 'There was a problem with your request.',
    icon: 'i-lucide-wifi',
    color: props.color
  })
}
</script>
<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>
Close
Pass a close field to customize or hide the close Button (with false value).
<script setup lang="ts">
const toast = useToast()
function showToast() {
  toast.add({
    title: 'Uh oh! Something went wrong.',
    description: 'There was a problem with your request.',
    icon: 'i-lucide-wifi',
    close: {
      color: 'primary',
      variant: 'outline',
      class: 'rounded-full'
    }
  })
}
</script>
<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>
Close Icon
Pass a closeIcon field to customize the close button Icon. Default to i-lucide-x.
<script setup lang="ts">
const props = defineProps<{
  closeIcon: string
}>()
const toast = useToast()
function showToast() {
  toast.add({
    title: 'Uh oh! Something went wrong.',
    description: 'There was a problem with your request.',
    closeIcon: props.closeIcon
  })
}
</script>
<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>
Actions
Pass an actions field to add some Button actions to the Toast.
<script setup lang="ts">
const toast = useToast()
const props = defineProps<{
  description: string
}>()
function showToast() {
  toast.add({
    title: 'Uh oh! Something went wrong.',
    description: props.description,
    actions: [{
      icon: 'i-lucide-refresh-cw',
      label: 'Retry',
      color: 'neutral',
      variant: 'outline',
      onClick: (e) => {
        e?.stopPropagation()
      }
    }]
  })
}
</script>
<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>
Progress New
Pass a progress field to customize or hide the Progress bar (with false value).
progress.color field.<script setup lang="ts">
const toast = useToast()
function showToast() {
  toast.add({
    title: 'Uh oh! Something went wrong.',
    description: 'There was a problem with your request.',
    icon: 'i-lucide-wifi',
    progress: false
  })
}
</script>
<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>
Orientation
Pass an orientation field to the toast.add method to change the orientation of the Toast.
<script setup lang="ts">
const toast = useToast()
const props = defineProps<{
  orientation: 'horizontal' | 'vertical'
}>()
function showToast() {
  toast.add({
    title: 'Uh oh! Something went wrong.',
    orientation: props.orientation,
    actions: [{
      icon: 'i-lucide-refresh-cw',
      label: 'Retry',
      color: 'neutral',
      variant: 'outline',
      onClick: (e) => {
        e?.stopPropagation()
      }
    }]
  })
}
</script>
<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>
Examples
Change global position
Change the toaster.position prop on the App component to change the position of the toasts.
<script setup lang="ts">
const toaster = { position: 'bottom-right' }
</script>
<template>
  <UApp :toaster="toaster">
    <NuxtPage />
  </UApp>
</template>
AppConfig to configure the position prop of the Toaster component globally.Change global duration
Change the toaster.duration prop on the App component to change the duration of the toasts.
<script setup lang="ts">
const toaster = { duration: 5000 }
</script>
<template>
  <UApp :toaster="toaster">
    <NuxtPage />
  </UApp>
</template>
AppConfig to configure the duration prop of the Toaster component globally.Stacked toasts
Set the toaster.expand prop to false on the App component to display stacked toasts.
<script setup lang="ts">
const toaster = { expand: true }
</script>
<template>
  <UApp :toaster="toaster">
    <NuxtPage />
  </UApp>
</template>
<script setup lang="ts">
const toast = useToast()
function addToCalendar() {
  const eventDate = new Date(Date.now() + Math.random() * 31536000000)
  const formattedDate = eventDate.toLocaleDateString('en-US', {
    month: 'short',
    day: 'numeric',
    year: 'numeric'
  })
  toast.add({
    title: 'Event added to calendar',
    description: `This event is scheduled for ${formattedDate}.`,
    icon: 'i-lucide-calendar-days'
  })
}
</script>
<template>
  <UButton
    label="Add to calendar"
    color="neutral"
    variant="outline"
    icon="i-lucide-plus"
    @click="addToCalendar"
  />
</template>
AppConfig to configure the expand prop of the Toaster component globally.API
Props
| Prop | Default | Type | 
|---|---|---|
| as | 
 | 
 The element or component this component should render as. | 
| title | ||
| description | 
 | |
| icon | 
 | |
| avatar | 
 
 | |
| color | 
 | 
 | 
| orientation | 
 | 
 The orientation between the content and the actions. | 
| close | 
 | 
 Display a close button to dismiss the toast.
 | 
| closeIcon | 
 | 
 The icon displayed in the close button. | 
| actions | 
 Display a list of actions: 
 
 | |
| progress | 
 | 
 Display a progress bar showing the toast's remaining duration.
 | 
| defaultOpen | 
 The open state of the dialog when it is initially rendered. Use when you do not need to control its open state. | |
| open | 
 The controlled open state of the dialog. Can be bind as  | |
| type | 
 Control the sensitivity of the toast for accessibility purposes. For toasts that are the result of a user action, choose  | |
| duration | 
 Time in milliseconds that toast should remain visible for. Overrides value
given to  | |
| ui | 
 | 
Slots
| Slot | Type | 
|---|---|
| leading | 
 | 
| title | 
 | 
| description | 
 | 
| actions | 
 | 
| close | 
 | 
Emits
| Event | Type | 
|---|---|
| pause | 
 | 
| escapeKeyDown | 
 | 
| resume | 
 | 
| swipeStart | |
| swipeMove | |
| swipeCancel | |
| swipeEnd | 
 | 
| update:open | 
 | 
Theme
export default defineAppConfig({
  ui: {
    toast: {
      slots: {
        root: 'relative group overflow-hidden bg-default shadow-lg rounded-lg ring ring-default p-4 flex gap-2.5 focus:outline-none',
        wrapper: 'w-0 flex-1 flex flex-col',
        title: 'text-sm font-medium text-highlighted',
        description: 'text-sm text-muted',
        icon: 'shrink-0 size-5',
        avatar: 'shrink-0',
        avatarSize: '2xl',
        actions: 'flex gap-1.5 shrink-0',
        progress: 'absolute inset-x-0 bottom-0',
        close: 'p-0'
      },
      variants: {
        color: {
          primary: {
            root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary',
            icon: 'text-primary'
          },
          secondary: {
            root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-secondary',
            icon: 'text-secondary'
          },
          success: {
            root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-success',
            icon: 'text-success'
          },
          info: {
            root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-info',
            icon: 'text-info'
          },
          warning: {
            root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-warning',
            icon: 'text-warning'
          },
          error: {
            root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-error',
            icon: 'text-error'
          },
          neutral: {
            root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-inverted',
            icon: 'text-highlighted'
          }
        },
        orientation: {
          horizontal: {
            root: 'items-center',
            actions: 'items-center'
          },
          vertical: {
            root: 'items-start',
            actions: 'items-start mt-2.5'
          }
        },
        title: {
          true: {
            description: 'mt-1'
          }
        }
      },
      defaultVariants: {
        color: 'primary'
      }
    }
  }
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
export default defineConfig({
  plugins: [
    vue(),
    ui({
      ui: {
        toast: {
          slots: {
            root: 'relative group overflow-hidden bg-default shadow-lg rounded-lg ring ring-default p-4 flex gap-2.5 focus:outline-none',
            wrapper: 'w-0 flex-1 flex flex-col',
            title: 'text-sm font-medium text-highlighted',
            description: 'text-sm text-muted',
            icon: 'shrink-0 size-5',
            avatar: 'shrink-0',
            avatarSize: '2xl',
            actions: 'flex gap-1.5 shrink-0',
            progress: 'absolute inset-x-0 bottom-0',
            close: 'p-0'
          },
          variants: {
            color: {
              primary: {
                root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary',
                icon: 'text-primary'
              },
              secondary: {
                root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-secondary',
                icon: 'text-secondary'
              },
              success: {
                root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-success',
                icon: 'text-success'
              },
              info: {
                root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-info',
                icon: 'text-info'
              },
              warning: {
                root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-warning',
                icon: 'text-warning'
              },
              error: {
                root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-error',
                icon: 'text-error'
              },
              neutral: {
                root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-inverted',
                icon: 'text-highlighted'
              }
            },
            orientation: {
              horizontal: {
                root: 'items-center',
                actions: 'items-center'
              },
              vertical: {
                root: 'items-start',
                actions: 'items-start mt-2.5'
              }
            },
            title: {
              true: {
                description: 'mt-1'
              }
            }
          },
          defaultVariants: {
            color: 'primary'
          }
        }
      }
    })
  ]
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import uiPro from '@nuxt/ui-pro/vite'
export default defineConfig({
  plugins: [
    vue(),
    uiPro({
      ui: {
        toast: {
          slots: {
            root: 'relative group overflow-hidden bg-default shadow-lg rounded-lg ring ring-default p-4 flex gap-2.5 focus:outline-none',
            wrapper: 'w-0 flex-1 flex flex-col',
            title: 'text-sm font-medium text-highlighted',
            description: 'text-sm text-muted',
            icon: 'shrink-0 size-5',
            avatar: 'shrink-0',
            avatarSize: '2xl',
            actions: 'flex gap-1.5 shrink-0',
            progress: 'absolute inset-x-0 bottom-0',
            close: 'p-0'
          },
          variants: {
            color: {
              primary: {
                root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary',
                icon: 'text-primary'
              },
              secondary: {
                root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-secondary',
                icon: 'text-secondary'
              },
              success: {
                root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-success',
                icon: 'text-success'
              },
              info: {
                root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-info',
                icon: 'text-info'
              },
              warning: {
                root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-warning',
                icon: 'text-warning'
              },
              error: {
                root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-error',
                icon: 'text-error'
              },
              neutral: {
                root: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-inverted',
                icon: 'text-highlighted'
              }
            },
            orientation: {
              horizontal: {
                root: 'items-center',
                actions: 'items-center'
              },
              vertical: {
                root: 'items-start',
                actions: 'items-start mt-2.5'
              }
            },
            title: {
              true: {
                description: 'mt-1'
              }
            }
          },
          defaultVariants: {
            color: 'primary'
          }
        }
      }
    })
  ]
})