Sonner for React: Toast Notifications Tutorial & Examples
A concise, practical guide to installing, configuring, and customizing Sonner toast notifications in React — including promise-based toasts, hooks, and accessibility tips.
Why Sonner for React toast notifications?
Sonner is a minimal, modern notification library that focuses on developer ergonomics: an easy-to-use Toaster component and a straightforward imperative API let you show toast messages (success, error, loading, info) with minimal boilerplate. If you’re building a React notification system or replacing heavier libraries, Sonner offers lightweight styling, sensible defaults, and fast integration.
For teams optimizing delivery speed and DX, Sonner’s API maps well to common workflows: simple one-liners to trigger messages and an extendable Toaster to control behavior like position, duration, and animations. That makes it ideal for in-app alerts, form feedback, or promise-based flows where you want an automatic loading → success/error lifecycle.
From an SEO and voice-search perspective, Sonner is great because it supports short, predictable commands (e.g., “Show toast success”) which makes it easy to document and find. It also plays nicely with accessibility-focused patterns when configured correctly, so your React toast messages can be both visible and perceivable by assistive tech.
Installation and quick setup
Installing Sonner takes seconds. In most React projects use npm or yarn to add the package, then render the Toaster at the top level of your app. This ensures any component can call the toast API and the UI will be injected once.
Example install commands (pick one):
npm install sonneryarn add sonner
After installation, place the Toaster in your root component (App or layout). The Toaster handles container placement, stacking, and default accessibility attributes so you rarely need extra setup.
// App.jsx
import React from 'react';
import { Toaster } from 'sonner';
export default function App() {
return (
<>
{/* rest of your app */}
>
);
}
If you prefer a guided example, the community has useful tutorials such as Advanced Toast Notifications with Sonner. The official package is also available on npm (sonner), and the React docs provide basics on rendering components like Toaster at the app root.
Basic usage: showing toast messages
Sonner exposes a simple imperative API that you can call from anywhere once the Toaster is mounted. This pattern keeps components focused on business logic while the Toaster handles rendering and lifecycle.
Common methods include a generic toast and typed helpers. Examples below show immediate notifications for success, error, and info states. These calls are synchronous and return an id you can use to update or dismiss the toast later.
import { Toaster, toast } from 'sonner';
function SaveButton() {
async function handleSave() {
toast('Saving...');
try {
await api.save();
toast.success('Saved successfully 🎉');
} catch (err) {
toast.error('Save failed. Try again.');
}
}
return ;
}
Use these methods as building blocks in forms, navigation actions, or any user interaction where feedback is required. Sonner’s default styling is unobtrusive, so toasts don’t steal focus but remain clearly visible.
Because the API is declarative at the call site (call toast.*), it’s very friendly to unit testing and integration testing — you can mock or stub the toast object or assert that it was called with specific messages.
Working with promises: toast.promise
Promise-based toasts are the easiest way to show a loading state and then automatically switch to success or error. This is perfect for API requests or any async operation where you want a single line that reflects the full lifecycle.
The pattern is: call a helper like toast.promise(myPromise, { loading, success, error }). The library shows a loading toast, then updates it depending on the promise outcome. This avoids multiple manual calls and race conditions when handling concurrent requests.
// Example: toast.promise usage
function UploadButton({ file }) {
const upload = () => api.upload(file);
function handleUpload() {
toast.promise(
upload(),
{
loading: 'Uploading file...',
success: 'Upload complete ✅',
error: 'Upload failed.'
}
);
}
return ;
}
Promise toasts improve UX because users immediately see feedback that the app is working, and the message transitions naturally. Make sure error messages remain actionable — include steps or links if the failure can be resolved by the user.
If you need to customize the display during the loading phase (e.g., show progress), you can combine toast IDs with updates (store the returned id and call toast.update(id, {…})). This keeps a single visible toast and prevents spamming the UI with multiple messages.
Customization: styling, position, duration, and themes
Sonner’s Toaster accepts props to configure global behavior: where toasts appear (top-right, bottom-center, etc.), auto-close durations, and whether to show a close button. You can override default styles with CSS or by wrapping the toast content in your components for a design-system-compliant UI.
Common customization options you’ll adjust early are position and default duration. Shorter durations (2–3s) are good for non-critical info; keep errors or undo actions visible longer so users can respond. You can also disable auto-close for important alerts.
// Example: custom Toaster props
For theme integration, apply CSS variables or class overrides to match your app color tokens. If you’re using a component library, wrap toast children with your themed components so that icons, fonts, and spacing remain consistent across the app.
Finally, provide compact or dense variants where lists of toasts are likely (e.g., bulk actions). Custom animations are also possible if you want to emphasize entrance/exit behavior — just be mindful of motion preferences for accessibility.
Hooks, programmatic control, and advanced patterns
Most use cases only need the global toast API, but advanced scenarios require programmatic control: updating an existing toast, chaining toasts, or conditional rendering based on application state. Sonner supports programmatic updates using the toast ID returned from calls.
Use cases for programmatic control include progress updates (update the same toast with percent complete), replacing a loading toast with a success message, or implementing Undo patterns where an action can be reverted from the toast. For complex flows, keep toast logic close to the async action (e.g., in thunks or effects) to avoid scattered side effects.
If you rely on React hooks or contexts (for example, to access auth state or services), call toasts from inside effects or callbacks. Ensure the Toaster exists higher in the tree; otherwise, the toast API may be a no-op. In server-rendered environments, only call toasts on client-side events.
Best practices: accessibility, testing, and performance
Accessibility is non-negotiable for notifications. The Toaster should use ARIA live regions so screen readers announce messages without stealing keyboard focus. Confirm that your toast content is concise and descriptive; use links or buttons inside the toast for actions like “Retry” or “Undo”.
Testing toasts is simple: mock the toast API in unit tests and assert calls. For integration tests, query the DOM for the visible toast text and assert presence or dismissal timing. Avoid flakey tests by controlling durations in test environments (e.g., set duration to 0 for deterministic behavior).
For performance, keep toast payloads small — don’t render heavy components inside the toast unless necessary. Batch related messages (e.g., “3 items removed”) instead of firing many individual toasts for similar events to reduce visual noise and render churn.
Troubleshooting and common gotchas
If you see no toasts appearing, confirm the Toaster component is mounted at a common ancestor (App root) and not conditionally unmounted. Also check that you import the correct API names; a missing or misspelled import can result in silent failures.
Concurrent requests can create many toasts quickly. Debounce or collapse repeated messages (e.g., “Saved” after every keystroke) by consolidating update logic or using a single toast ID and calling update instead of creating new toasts.
When customizing styles, ensure you’re not inadvertently removing accessible attributes. For example, if you replace default markup, preserve ARIA roles and live region attributes or provide them yourself.
Quick API summary
<Toaster />— mount once; controls containertoast('text'),toast.success(...),toast.error(...)— immediate messagestoast.promise(promise, {loading, success, error})— lifecycle for async ops
These are the primitives you’ll use every day. They cover the majority of notification needs: instant feedback, typed messages, and promise-based transitions. With these in hand you can build undo flows, progress indicators, and ephemeral alerts with minimal code.
Resources and backlinks
Official package: Sonner on npm
Tutorial & examples: Advanced Toast Notifications with Sonner
React docs: React — Getting Started
FAQ
How do I install and set up Sonner in a React project?
Install with npm install sonner or yarn add sonner. Render <Toaster /> once at the top of your app (App.jsx). Then import and use the toast API anywhere: toast.success('Saved') or toast('Message'). This pattern keeps toasts globally available and easy to trigger.
How do I use toast.promise to show loading → success → error flows?
Wrap your async function call with toast.promise(promise, { loading, success, error }). Sonner shows the loading message while the promise resolves and automatically replaces it with either the success or error message based on the outcome. This reduces boilerplate and avoids manual state juggling.
How can I customize toast appearance, position, and duration?
Pass props to <Toaster /> or use a global options object (e.g., toastOptions) to set position, default duration, and closable behavior. For design integration, style the toast container or wrap toast content with your theme components to keep spacing, typography, and colors consistent with your app.
Semantic core (primary & related keyword clusters)
- sonner
- React toast notifications
- sonner tutorial
- React notification library
- sonner installation
- React toast messages
- sonner example
- React alert notifications
- sonner setup
- React toast hooks
- sonner customization
- React notification system
- sonner promise
- React toast library
Secondary / LSI phrases:
- toast notifications React
- toaster component
- toast.promise
- notification hooks
- toast styling
- auto-close duration
- position top-right bottom-left
- accessible toasts
- toast update dismiss
- promise-based toast
Clarifying long-tail queries:
- how to install sonner in react
- sonner example code
- sonner vs react-hot-toast
- customize sonner theme
- sonner toast.promise example
Leave A Comment