An opinionated toast component for React providing comprehensive toast notifications with customization options
npx @tessl/cli install tessl/npm-sonner@1.7.00
# Sonner
1
2
Sonner is an opinionated toast component for React that provides a comprehensive solution for displaying toast notifications. It offers a simple and intuitive API through a Toaster component and toast function, supporting various toast types including success, error, info, warning, loading, and custom toasts with actions.
3
4
## Package Information
5
6
- **Package Name**: sonner
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install sonner`
10
11
## Core Imports
12
13
```typescript
14
import { Toaster, toast } from "sonner";
15
```
16
17
For CommonJS:
18
19
```javascript
20
const { Toaster, toast } = require("sonner");
21
```
22
23
Additional imports for advanced usage:
24
25
```typescript
26
import {
27
Toaster,
28
toast,
29
useSonner,
30
type ExternalToast,
31
type ToasterProps,
32
type ToastT
33
} from "sonner";
34
```
35
36
## Basic Usage
37
38
```typescript
39
import React from "react";
40
import { Toaster, toast } from "sonner";
41
42
function App() {
43
return (
44
<div>
45
{/* Add Toaster component once in your app */}
46
<Toaster />
47
48
{/* Create toasts from anywhere */}
49
<button onClick={() => toast("Hello World!")}>
50
Show Toast
51
</button>
52
53
<button onClick={() => toast.success("Success!")}>
54
Success Toast
55
</button>
56
57
<button onClick={() => toast.error("Something went wrong!")}>
58
Error Toast
59
</button>
60
</div>
61
);
62
}
63
```
64
65
## Architecture
66
67
Sonner is built around several key components:
68
69
- **Toaster Component**: The container that renders all toast messages with positioning and theming
70
- **Toast Function**: The primary API for creating different types of toast notifications
71
- **State Management**: Built-in observer pattern for managing toast lifecycle and updates
72
- **Toast Types**: Pre-configured toast variants (success, error, info, warning, loading) with appropriate styling
73
- **Promise Integration**: Automatic state management for async operations with loading, success, and error states
74
- **Customization System**: Comprehensive theming, positioning, and styling options
75
- **Interaction System**: Support for swipe gestures, hover pause, keyboard navigation, and accessibility
76
77
## Capabilities
78
79
### Core Toast Functions
80
81
Primary toast creation functions for displaying notifications with different visual styles and behaviors.
82
83
```typescript { .api }
84
function toast(message: string | React.ReactNode, options?: ExternalToast): string | number;
85
86
// Type-specific toast functions
87
namespace toast {
88
function success(message: string | React.ReactNode, options?: ExternalToast): string | number;
89
function error(message: string | React.ReactNode, options?: ExternalToast): string | number;
90
function info(message: string | React.ReactNode, options?: ExternalToast): string | number;
91
function warning(message: string | React.ReactNode, options?: ExternalToast): string | number;
92
function loading(message: string | React.ReactNode, options?: ExternalToast): string | number;
93
function message(message: string | React.ReactNode, options?: ExternalToast): string | number;
94
function dismiss(id?: string | number): string | number | undefined;
95
function promise<T>(promise: PromiseT<T>, options: PromiseData<T>): { unwrap(): Promise<T> } & (string | number);
96
function custom(jsx: (id: string | number) => React.ReactElement, options?: ExternalToast): string | number;
97
function getHistory(): ToastT[];
98
function getToasts(): ToastT[];
99
}
100
```
101
102
[Core Toast Functions](./core-toast-functions.md)
103
104
### Toaster Component
105
106
The main React component that renders and manages all toast notifications with comprehensive configuration options.
107
108
```typescript { .api }
109
const Toaster: React.ForwardRefExoticComponent<ToasterProps & React.RefAttributes<HTMLElement>>;
110
111
interface ToasterProps {
112
invert?: boolean;
113
theme?: "light" | "dark" | "system";
114
position?: "top-left" | "top-right" | "bottom-left" | "bottom-right" | "top-center" | "bottom-center";
115
hotkey?: string[];
116
richColors?: boolean;
117
expand?: boolean;
118
duration?: number;
119
gap?: number;
120
visibleToasts?: number;
121
closeButton?: boolean;
122
toastOptions?: ToastOptions;
123
className?: string;
124
style?: React.CSSProperties;
125
offset?: Offset;
126
mobileOffset?: Offset;
127
dir?: "rtl" | "ltr" | "auto";
128
swipeDirections?: SwipeDirection[];
129
/** @deprecated Use icons prop instead */
130
loadingIcon?: React.ReactNode;
131
icons?: ToastIcons;
132
containerAriaLabel?: string;
133
pauseWhenPageIsHidden?: boolean;
134
}
135
```
136
137
[Toaster Component](./toaster-component.md)
138
139
### Advanced Toast Features
140
141
Advanced toast functionality including promise integration, custom JSX content, and action buttons.
142
143
```typescript { .api }
144
// Promise-based toasts
145
function toast.promise<T>(
146
promise: Promise<T> | (() => Promise<T>),
147
options: PromiseData<T>
148
): { unwrap(): Promise<T> } & (string | number);
149
150
// Custom JSX toasts
151
function toast.custom(
152
jsx: (id: string | number) => React.ReactElement,
153
options?: ExternalToast
154
): string | number;
155
156
// Toast state management
157
function toast.getHistory(): ToastT[];
158
function toast.getToasts(): ToastT[];
159
```
160
161
[Advanced Toast Features](./advanced-toast-features.md)
162
163
### React Hooks
164
165
React hooks for integrating with toast state and managing toast notifications programmatically.
166
167
```typescript { .api }
168
function useSonner(): {
169
toasts: ToastT[];
170
};
171
```
172
173
[React Hooks](./react-hooks.md)
174
175
## Core Types
176
177
```typescript { .api }
178
interface ExternalToast {
179
id?: string | number;
180
type?: "normal" | "action" | "success" | "info" | "warning" | "error" | "loading" | "default";
181
icon?: React.ReactNode;
182
jsx?: React.ReactNode;
183
richColors?: boolean;
184
invert?: boolean;
185
closeButton?: boolean;
186
dismissible?: boolean;
187
description?: (() => React.ReactNode) | React.ReactNode;
188
duration?: number;
189
action?: Action | React.ReactNode;
190
cancel?: Action | React.ReactNode;
191
onDismiss?: (toast: ToastT) => void;
192
onAutoClose?: (toast: ToastT) => void;
193
cancelButtonStyle?: React.CSSProperties;
194
actionButtonStyle?: React.CSSProperties;
195
style?: React.CSSProperties;
196
unstyled?: boolean;
197
className?: string;
198
classNames?: ToastClassnames;
199
descriptionClassName?: string;
200
position?: Position;
201
}
202
203
interface Action {
204
label: React.ReactNode;
205
onClick: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
206
actionButtonStyle?: React.CSSProperties;
207
}
208
209
interface ToastT {
210
id: number | string;
211
title?: (() => React.ReactNode) | React.ReactNode;
212
type?: "normal" | "action" | "success" | "info" | "warning" | "error" | "loading" | "default";
213
icon?: React.ReactNode;
214
jsx?: React.ReactNode;
215
richColors?: boolean;
216
invert?: boolean;
217
closeButton?: boolean;
218
dismissible?: boolean;
219
description?: (() => React.ReactNode) | React.ReactNode;
220
duration?: number;
221
delete?: boolean;
222
action?: Action | React.ReactNode;
223
cancel?: Action | React.ReactNode;
224
onDismiss?: (toast: ToastT) => void;
225
onAutoClose?: (toast: ToastT) => void;
226
promise?: Promise<any> | (() => Promise<any>);
227
cancelButtonStyle?: React.CSSProperties;
228
actionButtonStyle?: React.CSSProperties;
229
style?: React.CSSProperties;
230
unstyled?: boolean;
231
className?: string;
232
classNames?: ToastClassnames;
233
descriptionClassName?: string;
234
position?: Position;
235
}
236
237
type Position = "top-left" | "top-right" | "bottom-left" | "bottom-right" | "top-center" | "bottom-center";
238
239
type SwipeDirection = "top" | "right" | "bottom" | "left";
240
241
interface ToastClassnames {
242
toast?: string;
243
title?: string;
244
description?: string;
245
loader?: string;
246
closeButton?: string;
247
cancelButton?: string;
248
actionButton?: string;
249
success?: string;
250
error?: string;
251
info?: string;
252
warning?: string;
253
loading?: string;
254
default?: string;
255
content?: string;
256
icon?: string;
257
}
258
259
interface ToastIcons {
260
success?: React.ReactNode;
261
info?: React.ReactNode;
262
warning?: React.ReactNode;
263
error?: React.ReactNode;
264
loading?: React.ReactNode;
265
close?: React.ReactNode;
266
}
267
268
type Offset = {
269
top?: string | number;
270
right?: string | number;
271
bottom?: string | number;
272
left?: string | number;
273
} | string | number;
274
275
interface PromiseData<ToastData = any> {
276
loading?: string | React.ReactNode;
277
success?: string | React.ReactNode | ((data: ToastData) => React.ReactNode | string | Promise<React.ReactNode | string>);
278
error?: string | React.ReactNode | ((error: any) => React.ReactNode | string | Promise<React.ReactNode | string>);
279
description?: string | React.ReactNode | ((data: any) => React.ReactNode | string | Promise<React.ReactNode | string>);
280
finally?: () => void | Promise<void>;
281
}
282
283
type PromiseT<Data = any> = Promise<Data> | (() => Promise<Data>);
284
285
type PromiseExternalToast = Omit<ExternalToast, 'description'>;
286
```