Components
'use client';
import { Button } from '@/registry/san-francisco/ui/button';
import { Toaster } from '@/registry/san-francisco/ui/sonner';
import { toast } from 'sonner';
export default function SonnerDemo() {
return (
<>
<div className="flex w-full flex-wrap justify-center gap-2">
<Button variant="outline" onClick={() => toast('Event has been created')}>
Default
</Button>
<Button variant="outline" onClick={() => toast.success('Event has been created')}>
Success
</Button>
<Button variant="outline" onClick={() => toast.info('Be at the area 10 minutes before the event time')}>
Info
</Button>
<Button variant="outline" onClick={() => toast.warning('Event start time cannot be earlier than 8am')}>
Warning
</Button>
<Button variant="outline" onClick={() => toast.error('Event has not been created')}>
Error
</Button>
<Button
variant="outline"
onClick={() => {
toast.promise<{ name: string }>(
() => new Promise((resolve) => setTimeout(() => resolve({ name: 'Event' }), 2000)),
{
loading: 'Loading...',
success: (data) => `${data.name} has been created`,
error: 'Error',
},
);
}}
>
Promise
</Button>
</div>
<Toaster />
</>
);
}
bunx shadcn@latest add @sft-ui/sonner
Add the Toaster once in your root layout (or another parent that wraps your app) so toasts can render:
import { Toaster } from '@/components/ui/sonner';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
<Toaster />
</body>
</html>
);
}
Sonner is built and maintained by emilkowalski. See the Sonner documentation for the full API. The shadcn/ui Sonner docs show additional examples (description, position, actions).