Get Started
Input
Feedback
Display
Installation
i18n
"use client"
import { toast } from "sonner"About#
Sonner is built and maintained by emilkowalski.
Installation#
Run the following command:
pnpm dlx shadcn@latest add https://ui.tyap.me/r/styles/base/sonner.jsonnpx shadcn@latest add https://ui.tyap.me/r/styles/base/sonner.jsonyarn dlx shadcn@latest add https://ui.tyap.me/r/styles/base/sonner.jsonbunx --bun shadcn@latest add https://ui.tyap.me/r/styles/base/sonner.json
Add the Toaster component.
import { Toaster } from "@/components/ui/sonner"
export default function RootLayout({ children }) {
return (
<html lang="en">
<head />
<body>
<main>{children}</main>
<Toaster />
</body>
</html>
)
}Install the following dependencies:
pnpm add sonner next-themesnpm install sonner next-themesyarn add sonner next-themesbun add sonner next-themes
Copy and paste the following code into your project.
"use client"
import * as React from "react"
import { useTheme } from "next-themes"
import { Toaster as Sonner, toast, type ToasterProps } from "sonner"
import { cn } from "@/lib/utils"
import { CircleCheckIcon, InfoIcon, TriangleAlertIcon, OctagonXIcon, Loader2Icon } from "lucide-react"
function IconBadge({
children,
className,
}: {
children: React.ReactNode
className: string
}) {
return (
<div
className={cn(
"flex size-7 shrink-0 items-center justify-center rounded-xl",
className
)}
>
{children}
</div>
)
}
const Toaster = ({ ...props }: ToasterProps) => {
const { theme = "system" } = useTheme()
return (
<Sonner
theme={theme as ToasterProps["theme"]}
className="toaster group"
icons={{
success: (
<IconBadge className="bg-emerald-500/10 text-emerald-600 dark:text-emerald-400">
<CircleCheckIcon className="size-3.5" />
</IconBadge>
),
info: (
<IconBadge className="bg-blue-500/10 text-blue-600 dark:text-blue-400">
<InfoIcon className="size-3.5" />
</IconBadge>
),
warning: (
<IconBadge className="bg-amber-500/10 text-amber-600 dark:text-amber-400">
<TriangleAlertIcon className="size-3.5" />
</IconBadge>
),
error: (
<IconBadge className="bg-red-500/10 text-red-600 dark:text-red-400">
<OctagonXIcon className="size-3.5" />
</IconBadge>
),
loading: (
<IconBadge className="bg-foreground/5 text-foreground/50">
<Loader2Icon className="size-3.5 animate-spin" />
</IconBadge>
),
}}
style={
{
"--normal-bg": "var(--popover)",
"--normal-text": "var(--popover-foreground)",
"--normal-border": "var(--border)",
"--border-radius": "var(--radius-2xl)",
"--toast-icon-margin-start": "-2px",
"--toast-icon-margin-end": "6px",
"--toast-close-button-start": "auto",
"--toast-close-button-end": "0",
"--toast-close-button-transform": "translate(35%, -35%)",
} as React.CSSProperties
}
closeButton
toastOptions={{
classNames: {
toast: "rounded-2xl group/toast [&_[data-icon]]:!size-7",
title: "!text-sm !font-semibold",
description: "!text-[0.8rem] !leading-snug !text-muted-foreground",
actionButton:
"!bg-primary !text-primary-foreground !text-xs !font-medium !rounded-4xl !h-7 !px-3 !py-0",
cancelButton:
"!bg-muted !text-muted-foreground !text-xs !font-medium !rounded-4xl !h-7 !px-3 !py-0 hover:!bg-muted/80",
closeButton:
"!size-7 !rounded-4xl !bg-background !border !border-border/30 !shadow-none !text-muted-foreground hover:!bg-muted hover:!text-foreground opacity-0 group-hover/toast:opacity-100 !transition-all !duration-150 [&_svg]:!size-3.5 !p-0",
},
}}
{...props}
/>
)
}
export { toast, Toaster }
Add the Toaster component.
import { Toaster } from "@/components/ui/sonner"
export default function RootLayout({ children }) {
return (
<html lang="en">
<head />
<body>
<Toaster />
<main>{children}</main>
</body>
</html>
)
}Usage#
import { toast } from "sonner"toast("Event has been created.")Examples#
Types#
"use client"
import { toast } from "sonner"Description#
"use client"
import { toast } from "sonner"Position#
Use the position prop to change the position of the toast.
"use client"
import { toast } from "sonner"API Reference#
See the Sonner API Reference for more information.