Use the useToast composable to display a toast in your application.
<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>
Make sure to wrap your app with the App component which uses our Toaster component which uses the ToastProvider component from Reka UI.
You can check the App component toaster prop to see how to configure the Toaster globally.
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>
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>
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>
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>
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>
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>
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>
You can customize this icon globally in your app.config.ts under ui.icons.close key.
You can customize this icon globally in your vite.config.ts under ui.icons.close key.
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>
Pass a progress field to customize or hide the Progress bar (with false value).
The Progress bar inherits the Toast color by default, but you can override it using the 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>
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>
Nuxt UI provides an App component that wraps your app to provide global configurations.
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>
In this example, we use the AppConfig to configure the position prop of the Toaster component globally.
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>
In this example, we use the AppConfig to configure the duration prop of the Toaster component globally.
Change the toaster.max prop on the App component to change the max number of toasts displayed at once.
<script setup lang="ts">
const toaster = { max: 3 }
</script>
<template>
<UApp :toaster="toaster">
<NuxtPage />
</UApp>
</template>
In this example, we use the AppConfig to configure the max prop of the Toaster component globally.
Set the toaster.expand prop to false on the App component to display stacked toasts (inspired by Sonner).
<script setup lang="ts">
const toaster = { expand: true }
</script>
<template>
<UApp :toaster="toaster">
<NuxtPage />
</UApp>
</template>
You can hover over the toasts to expand them. This will also pause the timer of the toasts.
<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>
In this example, we use the AppConfig to configure the expand prop of the Toaster component globally.
| 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 |
|
| Slot | Type |
|---|---|
leading |
|
title |
|
description |
|
actions |
|
close |
|
| Event | Type |
|---|---|
pause | |
escapeKeyDown |
|
resume |
|
swipeStart | |
swipeMove | |
swipeCancel | |
swipeEnd |
|
update:open |
|
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'
}
}
}
})
]
})
5cb65 — feat: import @nuxt/ui-pro components
ec569 — feat: progress bar with Progress component
1d052 — fix: only show progress when open
3bf5a — fix: calc height on next tick
e6e51 — fix: class should have priority over ui prop
50863 — fix: display actions when using slots
f4c41 — fix: prevent unnecessary close instantiation