Join our Discord Community

Sonner

An opinionated toast component for React. Perfect for notifications, confirmations, and user feedback in Next.js, TypeScript, and Tailwind CSS applications.

You know those little notifications that pop up to tell you something worked? Or when you need to undo an action? Sonner makes toast notifications feel polished and thoughtful instead of jarring interruptions that users immediately dismiss.

Basic notification

Clean, simple toast messages:

Loading component...

Just import and call toast() anywhere in your app. This free open source React component handles positioning, animations, and accessibility so your notifications feel professional.

npx shadcn@latest add sonner

Why Sonner beats basic alerts

Toast notifications done right actually improve user experience:

  • Non-blocking - Users can keep working while notifications show
  • Contextual timing - Messages appear exactly when they're relevant
  • Undo actions - Let users reverse mistakes immediately
  • Status updates - Show loading, success, and error states naturally
  • Swipe to dismiss - Intuitive mobile-friendly interactions
  • Smart positioning - Never covers important interface elements

Toast types for every situation

Different message types

Success, error, loading, and default styles:

Loading component...

Promise handling

Automatic loading states for async operations:

Loading component...

Custom notifications

Icons, persistence, and completely custom JSX:

Loading component...

These patterns cover real scenarios - form submissions, file uploads, API calls, user actions. Each toast type gives users the right visual cue for what's happening.

Perfect for user feedback

Sonner shines when you need to confirm actions, show progress, or let users undo things. Works great with forms, data operations, settings changes, bulk actions. Much better than modal dialogs that force users to stop what they're doing.

Built by Emil Kowalski. Full TypeScript support. Styled with Tailwind CSS to match the shadcn design system.

Setup

Add the Toaster component to your root layout:

import { Toaster } from "@repo/shadcn-ui/components/ui/sonner"

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <main>{children}</main>
        <Toaster />
      </body>
    </html>
  )
}

API Reference

toast()

The main function for creating toast notifications.

FunctionDescription
toast(message, options?)Basic toast with message and optional config
toast.success(message, options?)Success toast with checkmark icon
toast.error(message, options?)Error toast with error icon
toast.loading(message, options?)Loading toast with spinner
toast.promise(promise, options)Handles promise states automatically
toast.custom(jsx, options?)Completely custom toast content
toast.dismiss(id?)Dismiss specific toast or all toasts

Toast Options

Configuration object for customizing individual toasts:

OptionTypeDefaultDescription
descriptionstring | ReactNode-Additional text below the main message
durationnumber4000Time in milliseconds before auto-dismissal
actionobject-Primary button with label and onClick handler
cancelobject-Secondary button with label and onClick handler
iconReactNode-Custom icon to display
closeButtonbooleanfalseShow close button
dismissiblebooleantrueAllow user dismissal
idstring-Custom ID for programmatic control
positionstring-Override default position for this toast
onDismiss(toast) => void-Callback when toast is dismissed
onAutoClose(toast) => void-Callback when toast auto-closes
classNamestring-Additional CSS classes
styleobject-Inline styles
unstyledbooleanfalseRemove default styling

Promise Options

Special configuration for promise-based toasts:

OptionTypeDescription
loadingstring | ReactNodeMessage during promise execution
successstring | functionMessage or function returning message on success
errorstring | functionMessage or function returning message on error
toast.promise(uploadFile(), {
  loading: "Uploading...",
  success: (data) => `${data.filename} uploaded successfully`,
  error: "Upload failed",
})

Toaster Component

Container component that renders all toasts:

PropTypeDefaultDescription
positionstringbottom-rightWhere toasts appear on screen
expandbooleanfalseExpand toasts by default
visibleToastsnumber3Maximum number of visible toasts
closeButtonbooleanfalseAdd close button to all toasts
richColorsbooleanfalseEnhanced colors for success/error states
theme'light' | 'dark' | 'system'lightColor theme
offsetstring32pxDistance from screen edges
dir'ltr' | 'rtl' | 'auto'ltrText direction
hotkeystring[]['⌥', 'T']Keyboard shortcut to focus toasts
toastOptionsobject{}Default options for all toasts

Available Positions

PositionDescription
top-leftUpper left corner
top-centerTop center of screen
top-rightUpper right corner
bottom-leftLower left corner
bottom-centerBottom center of screen
bottom-rightLower right corner (default)

Common patterns

Form submission feedback

const handleSubmit = async (data) => {
  const promise = submitForm(data)
  
  toast.promise(promise, {
    loading: "Saving changes...",
    success: "Settings updated successfully",
    error: "Failed to save changes",
  })
}

Undo actions

const deleteItem = (id) => {
  // Perform deletion
  removeItem(id)
  
  toast("Item deleted", {
    action: {
      label: "Undo",
      onClick: () => restoreItem(id),
    },
  })
}

Persistent notifications

const showImportantMessage = () => {
  const id = toast("System maintenance in 5 minutes", {
    duration: Infinity,
    action: {
      label: "Dismiss",
      onClick: () => toast.dismiss(id),
    },
  })
}

Design tips for better toasts

Keep these principles in mind when using toast notifications:

  • Be specific - "File uploaded" is better than "Success"
  • Show progress - Use loading states for operations that take time
  • Enable undo - Let users reverse destructive actions immediately
  • Don't overuse - Too many toasts become noise users ignore
  • Time appropriately - Important messages can stay longer
  • Position thoughtfully - Don't cover critical interface elements
  • Test on mobile - Make sure swipe gestures work naturally
  • Consider accessibility - Screen readers should announce toast content