Skip to main content
The Toast component provides temporary notifications that appear at the edge of the screen. It supports multiple variants, actions, promise handling, and anchored positioning.

Installation

npx shadcn@latest add @eo-n/toast

Usage

Setup Provider

Add the ToastProvider to your app layout:
layout.tsx
import { ToastProvider } from "@/components/ui/toast";

<html lang="en">
  <body>
    <ToastProvider>{children}</ToastProvider>
  </body>
</html>

Show Toasts

Use toastManager to display toasts from anywhere in your app:
import { toastManager } from "@/components/ui/toast";
import { Button } from "@/components/ui/button";

export default function Example() {
  return (
    <Button
      onClick={() => {
        toastManager.add({
          title: "Profile Updated",
          description: "Your changes have been saved.",
        });
      }}
    >
      Save Changes
    </Button>
  );
}
The toastManager can be called from anywhere, including outside of React components. No hooks required.

Examples

Basic Toast

import { toastManager } from "@/components/ui/toast";

toastManager.add({
  title: "Success",
  description: "Your action completed successfully.",
});

Toast Variants

// Success
toastManager.add({
  type: "success",
  title: "Changes saved",
  description: "Your profile has been updated.",
});

// Error
toastManager.add({
  type: "error",
  title: "Error occurred",
  description: "Unable to save your changes.",
});

// Warning
toastManager.add({
  type: "warning",
  title: "Warning",
  description: "Your session will expire soon.",
});

// Info
toastManager.add({
  type: "info",
  title: "Tip",
  description: "You can customize your workspace in settings.",
});

// Loading
toastManager.add({
  type: "loading",
  title: "Processing",
  description: "Please wait while we process your request.",
});

With Action Button

import { toastManager } from "@/components/ui/toast";

toastManager.add({
  title: "File deleted",
  description: "Your file has been moved to trash.",
  actionText: "Undo",
  onAction: () => {
    console.log("Undo action triggered");
  },
});

Promise-based Toast

Automatically show loading, success, or error states:
import { toastManager } from "@/components/ui/toast";

const uploadPromise = uploadFile(file);

toastManager.promise(uploadPromise, {
  loading: {
    title: "Uploading...",
    description: "Please wait while we upload your file.",
  },
  success: (data) => ({
    title: "Upload complete",
    description: `${data.filename} has been uploaded successfully.`,
  }),
  error: (error) => ({
    title: "Upload failed",
    description: error.message,
  }),
});

Custom Duration

toastManager.add({
  title: "Quick notification",
  timeout: 2000, // 2 seconds
});

// Persistent (won't auto-dismiss)
toastManager.add({
  title: "Important message",
  timeout: null,
});

Anchored Toast

Anchor toasts to specific elements (useful for copy-to-clipboard feedback):
layout.tsx
import { AnchoredToastProvider, ToastProvider } from "@/components/ui/toast";

<ToastProvider>
  <AnchoredToastProvider>{children}</AnchoredToastProvider>
</ToastProvider>
import { useRef } from "react";
import { anchoredToastManager } from "@/components/ui/toast";
import { Button } from "@/components/ui/button";

export default function CopyButton() {
  const buttonRef = useRef<HTMLButtonElement>(null);

  function handleCopy() {
    navigator.clipboard.writeText("Hello world");
    
    anchoredToastManager.add({
      description: "Copied to clipboard!",
      positionerProps: {
        anchor: buttonRef.current,
        sideOffset: 8,
      },
      timeout: 1500,
    });
  }

  return (
    <Button ref={buttonRef} onClick={handleCopy}>
      Copy
    </Button>
  );
}

Custom Position

<ToastProvider position="top-center">
  {children}
</ToastProvider>
Available positions:
  • top-center
  • top-left
  • top-right
  • bottom-center (default)
  • bottom-left
  • bottom-right

Rich Colors

Enable variant-specific background colors:
<ToastProvider richColors>
  {children}
</ToastProvider>

With Close Button

<ToastProvider closeButton>
  {children}
</ToastProvider>

Component API

ToastProvider

position
'top-center' | 'top-left' | 'top-right' | 'bottom-center' | 'bottom-left' | 'bottom-right'
Where to display toasts on the screen. Defaults to bottom-right.
richColors
boolean
Enable variant-specific background colors. Defaults to false.
closeButton
boolean
Show a close button on each toast. Defaults to false.
maxToasts
number
Maximum number of toasts to display at once.
children
React.ReactNode
required
Your app content.

toastManager.add()

type
'default' | 'success' | 'error' | 'warning' | 'info' | 'loading'
The visual variant of the toast.
title
string
The toast title.
description
string
The toast description.
actionText
string
Text for the action button.
onAction
() => void
Callback when action button is clicked.
timeout
number | null
Auto-dismiss delay in milliseconds. Pass null to disable auto-dismiss. Defaults to 5000.
onClose
() => void
Callback when toast is dismissed.

toastManager.promise()

promise
Promise<T>
required
The promise to track.
loading
ToastOptions
Toast options to show while loading.
success
ToastOptions | ((data: T) => ToastOptions)
Toast options to show on success.
error
ToastOptions | ((error: Error) => ToastOptions)
Toast options to show on error.

Accessibility

The Toast component includes:
  • ARIA live regions for screen reader announcements
  • Keyboard navigation (ESC to dismiss)
  • Focus management
  • Swipe gestures for touch devices
  • Proper semantic markup

Reference

Built on top of Base UI Toast.

Build docs developers (and LLMs) love