---
import { Button } from "@/components/ui/button"
import { Toaster } from "@/components/ui/toast"
---
<div class="flex flex-wrap gap-2">
<Button id="show-basic-toast" variant="outline">Show toast</Button>
<Button id="show-action-toast" variant="outline">Toast with action</Button>
</div>
<Toaster id="example-toaster" portal />
<script>
const initializeToastDemo = () => {
const toaster = document.getElementById("example-toaster")
const basicButton = document.getElementById("show-basic-toast")
const actionButton = document.getElementById("show-action-toast")
if (basicButton) {
basicButton.onclick = () => {
toaster?.dispatchEvent(
new CustomEvent("toast:show", {
detail: {
title: "Event created",
description: "Sunday, December 3 at 9:00 AM",
type: "success",
},
})
)
}
}
if (actionButton) {
actionButton.onclick = () => {
toaster?.dispatchEvent(
new CustomEvent("toast:show", {
detail: {
title: "Event created",
description: "You can undo this action.",
action: { label: "Undo", value: "undo-event" },
},
})
)
}
}
}
initializeToastDemo()
document.addEventListener("astro:page-load", initializeToastDemo)
</script>Installation
npx shadcn@latest add @fulldev/toast
Usage
Place one Toaster in the page shell or layout. Give it an ID when commands
need a stable target.
---
import { Toaster } from "@/components/ui/toast"
---
<Toaster id="notifications" portal />
Show a notification by dispatching a toast:show event on that root.
const toaster = document.getElementById("notifications")
toaster?.dispatchEvent(
new CustomEvent("toast:show", {
detail: {
title: "Changes saved",
description: "All updates are synced.",
type: "success",
},
})
)
When Astro’s ClientRouter can replace the page containing your trigger,
reconnect page-specific event handlers on astro:page-load. Keep a toaster in
the shared layout when the notification API should remain available across
route changes. Active notifications are reset during a route swap; persist any
notification data in your own application state when it must survive.
Options
Toaster accepts these runtime options as props:
limit: maximum visible notifications, default3duration: automatic dismissal delay in milliseconds, default5000; use0for persistent notificationsposition:top-left,top-center,top-right,bottom-left,bottom-center, orbottom-rightpauseOnHoverandpauseOnFocus: pause active timers during interactionportal: move the viewport todocument.body
Toast data accepts id, title, description, type, duration, action,
dismissible, closeButtonAriaLabel, and testId. title is required. Types
are default, success, error, warning, info, and loading.
Commands
The root listens for framework-neutral DOM events.
// Show and keep a stable ID for later updates.
toaster.dispatchEvent(
new CustomEvent("toast:show", {
detail: { id: "upload", title: "Uploading", type: "loading", duration: 0 },
})
)
// Patch an active toast.
toaster.dispatchEvent(
new CustomEvent("toast:update", {
detail: { id: "upload", title: "Upload complete", type: "success" },
})
)
// Dismiss one toast or clear all active toasts.
toaster.dispatchEvent(
new CustomEvent("toast:dismiss", { detail: { id: "upload" } })
)
toaster.dispatchEvent(new CustomEvent("toast:clear"))
The root emits toast:change with { id, action: "show" | "dismiss" } and
toast:action with { id, value }. Listen for toast:action to handle action
buttons.
toaster.addEventListener("toast:action", (event) => {
if (event.detail.value === "undo-event") {
// Undo the operation here.
}
})
For controller access, import createToast from @data-slot/toast. Its
show, update, promise, dismiss, and dismissAll methods use the same
data model. The Astro Toast component already initializes roots, so create a
controller directly only when you own initialization yourself.
Custom template
Toaster includes the standard template and viewport. Use the lower-level
parts when you need different markup or classes.
---
import {
Toast,
ToastAction,
ToastClose,
ToastContent,
ToastDescription,
ToastIcon,
ToastItem,
ToastTemplate,
ToastTitle,
ToastViewport,
} from "@/components/ui/toast"
---
<Toast id="notifications">
<ToastTemplate>
<ToastItem>
<ToastContent>
<ToastIcon />
<div class="min-w-0 flex-1">
<ToastTitle />
<ToastDescription />
</div>
<ToastAction />
<ToastClose />
</ToastContent>
</ToastItem>
</ToastTemplate>
<ToastViewport />
</Toast>
API Reference
See the GitHub source code for component props. See the data-slot docs for controller methods, promise notifications, timers, stacking, swipe dismissal, and events.