## Features
- 🔥 **Hot by default**
- 🔩 **Easily Customizable**
- ⏳ **Promise API** - _Automatic loader from a promise_
- 🕊 **Lightweight** - _less than 5kb including styles_
- ✅ **Accessible**
- 🤯 **Headless Hooks** - _Create your own with [`useToaster()`](https://react-hot-toast.com/docs/use-toaster)_
## Installation
#### With pnpm
```sh
pnpm add react-hot-toast
```
#### With NPM
```sh
npm install react-hot-toast
```
## Getting Started
Add the Toaster to your app first. It will take care of rendering all notifications emitted. Now you can trigger `toast()` from anywhere!
```jsx
import toast, { Toaster } from 'react-hot-toast';
const notify = () => toast('Here is your toast.');
const App = () => {
return (
);
};
```
## Documentation
Find the full API reference on [official documentation](https://react-hot-toast.com/docs).
================================================
FILE: jest.config.js
================================================
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['/test/setup.ts'],
};
================================================
FILE: package.json
================================================
{
"name": "react-hot-toast",
"description": "Smoking hot React Notifications. Lightweight, customizable and beautiful by default.",
"version": "2.6.0",
"author": "Timo Lins",
"license": "MIT",
"repository": "timolins/react-hot-toast",
"keywords": [
"react",
"notifications",
"toast",
"snackbar"
],
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
"./package.json": "./package.json",
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
},
"./headless": {
"types": "./headless/index.d.ts",
"import": "./headless/index.mjs",
"require": "./headless/index.js"
}
},
"files": [
"headless",
"dist",
"src"
],
"engines": {
"node": ">=10"
},
"scripts": {
"start": "tsup --watch",
"build": "tsup",
"test": "jest --runInBand",
"setup": "pnpm i && cd site && pnpm i && cd .. && pnpm run link",
"link": "pnpm link ./site/node_modules/react && pnpm link ./site/node_modules/react-dom",
"size": "size-limit"
},
"husky": {
"hooks": {
"pre-commit": "prettier src --ignore-unknown --write"
}
},
"prettier": {
"printWidth": 80,
"semi": true,
"singleQuote": true,
"arrowParens": "always",
"trailingComma": "es5"
},
"size-limit": [
{
"path": "dist/index.js",
"limit": "5.5 KB"
},
{
"path": "dist/index.mjs",
"limit": "5.5 KB"
},
{
"path": "headless/index.js",
"limit": "2.5 KB"
},
{
"path": "headless/index.mjs",
"limit": "2.5 KB"
}
],
"devDependencies": {
"@jest/types": "^29.6.3",
"@size-limit/preset-small-lib": "^7.0.8",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.1.0",
"@types/jest": "^29.5.14",
"@types/react": "^18.3.18",
"@types/react-dom": "^18.3.5",
"esbuild-minify-templates": "^0.13.1",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"prettier": "^2.8.8",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"size-limit": "^7.0.8",
"ts-jest": "^29.2.5",
"tslib": "^2.8.1",
"tsup": "^6.7.0",
"typescript": "^5.7.2"
},
"dependencies": {
"csstype": "^3.1.3",
"goober": "^2.1.16"
},
"peerDependencies": {
"react": ">=16",
"react-dom": ">=16"
},
"packageManager": "pnpm@9.15.4+sha512.b2dc20e2fc72b3e18848459b37359a32064663e5627a51e4c74b2c29dd8e8e0491483c3abb40789cfd578bf362fb6ba8261b05f0387d76792ed6e23ea3b1b6a0"
}
================================================
FILE: site/.gitignore
================================================
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local
# vercel
.vercel
================================================
FILE: site/README.md
================================================
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
## Getting Started
First, run the development server:
```bash
npm run dev
# or
yarn dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/import?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
================================================
FILE: site/components/code.tsx
================================================
import clsx from 'clsx';
import Highlight, {
defaultProps,
Language,
PrismTheme,
} from 'prism-react-renderer';
const theme: PrismTheme = {
plain: {
backgroundColor: '#351e11',
color: '#d6ceff',
},
styles: [
{
types: ['comment', 'prolog', 'doctype', 'cdata', 'punctuation'],
style: {
color: '#6c6783',
},
},
{
types: ['namespace'],
style: {
opacity: 0.7,
},
},
{
types: ['tag', 'operator', 'number', 'module'],
style: {
color: '#e09142',
},
},
{
types: ['property', 'function'],
style: {
color: '#9a86fd',
},
},
{
types: ['tag-id', 'selector', 'atrule-id'],
style: {
color: '#eeebff',
},
},
{
types: ['attr-name'],
style: {
color: '#c4b9fe',
},
},
{
types: [
'boolean',
'string',
'entity',
'url',
'attr-value',
'keyword',
'control',
'directive',
'unit',
'statement',
'regex',
'at-rule',
'placeholder',
'variable',
],
style: {
color: '#ffcc99',
},
},
{
types: ['deleted'],
style: {
textDecorationLine: 'line-through',
},
},
{
types: ['inserted'],
style: {
textDecorationLine: 'underline',
},
},
{
types: ['italic'],
style: {
fontStyle: 'italic',
},
},
{
types: ['important', 'bold'],
style: {
fontWeight: 'bold',
},
},
{
types: ['important'],
style: {
color: '#c4b9fe',
},
},
],
};
export const Code: React.FC<{
snippet: string;
language?: Language;
className?: string;
}> = (props) => {
const language = props.language || 'jsx';
return (
{({ className, style, tokens, getLineProps, getTokenProps }) => (
{tokens.map((line, i) => {
if (tokens.length - 1 === i && line[0].empty) {
return null;
}
return (
{line.map((token, key) => (
))}
);
})}
)}
);
};
================================================
FILE: site/components/docs-layout.tsx
================================================
import * as React from 'react';
import { Toaster } from 'react-hot-toast';
import { NextSeo } from 'next-seo';
import Link from 'next/link';
import { Footer } from './sections/footer';
import Logo from '../assets/logo-small.svg';
const TableItem: React.FC<{
href: string;
children?: React.ReactNode;
}> = ({ children, href }) => (
{children}
);
const TableHeader: React.FC<{
children?: React.ReactNode;
}> = ({ children }) => (
{children}
);
export default function DocsLayout({ meta, children }) {
return (
);
},
code: (props) =>
props.className ? (
) : (
),
};
function MyApp({ Component, pageProps }) {
return (
<>
{process.browser && (
)}
>
);
}
export default MyApp;
================================================
FILE: site/pages/docs/index.mdx
================================================
import Layout from '../../components/docs-layout';
import toast from 'react-hot-toast';
export const meta = {
title: 'Documentation',
};
export default ({ children }) => {children};
# Getting Started
Add beautiful notifications to your React app with [react-hot-toast](https://github.com/timolins/react-hot-toast).
### Install with pnpm
```sh
pnpm add react-hot-toast
```
### Install with NPM
```sh
npm install react-hot-toast
```
## Basic usage
```jsx
import toast, { Toaster } from 'react-hot-toast';
const notify = () => toast('Here is your toast.');
const App = () => {
return (
);
};
```
================================================
FILE: site/pages/docs/multi-toaster.mdx
================================================
import Layout from '../../components/docs-layout';
import toast, { Toaster } from 'react-hot-toast';
export const meta = {
title: 'Multiple Toasters',
};
export default ({ children }) => {children};
# Multiple Toasters
React Hot Toast supports multiple toaster instances in your app, They can be used and configured independently of each other. This is useful for having notifications in different areas of your app.
You can use multiple toasters by creating a [`Toaster`](/docs/toaster) with a unique `toasterId`:
```jsx
```
## Example
This example shows two toasters, each maintaining their own state and configuration.
Area 1
Area 2
## Basic Usage
You can create multiple toasters providing unique `toasterId` to each `` component:
```jsx
// Create a toaster with a unique id
// Create another toaster with a unique id
```
To create a toast in a specific toaster, you can pass the `toasterId` to the `toast` function.
```jsx
// Create a toast in area 1
toast('Notification for Area 1', {
toasterId: 'area1',
});
```
When no `toasterId` is provided, it uses `"default"` as the `toasterId`.
### Positioning the toaster
When placing a toaster in a specific area of your app, set the position to `absolute` and the parent element to `relative`.
```jsx
```
================================================
FILE: site/pages/docs/styling.mdx
================================================
import Layout from '../../components/docs-layout';
import toast from 'react-hot-toast';
export const meta = {
title: 'Styling',
};
export default ({ children }) => {children};
# Styling
You can style your notifications globally with the `toastOptions` inside the Toaster component, or for each notification manually.
### Set default for all toasts
```jsx
```
### Set default for specific types
```jsx
```
### Style per toast
```jsx
toast('I have a border.', {
style: {
border: '1px solid black',
},
});
```
## Change the offset
If you want to change the offset of your notifications, you can adapt the absolute position in `containerStyle`.
```jsx
```
## Change position of the toaster
By default, the toaster is position fixed in the window. If you want to place it somewhere else, you can overwrite the position with `containerStyle`.
```jsx
```
## Change offset between toasts
If you want to change the offset between notifications change the gutter.
```jsx
```
## Change icon color
All icon colors can be changed by supplying a `iconTheme` with a `primary` & `secondary` color.
```jsx
```
## Change enter and exit animations
In this example, we provide a render function with the default ``. We overwrite the animation style based on the current state.
```jsx
import { Toaster, ToastBar } from 'react-hot-toast';
{(t) => (
)}
;
```
================================================
FILE: site/pages/docs/toast-bar.mdx
================================================
import Layout from '../../components/docs-layout';
import toast from 'react-hot-toast';
export const meta = {
title: ' API',
};
export default ({ children }) => {children};
# `` API
This is the **default toast component** rendered by the [Toaster](/docs/toaster). You can use this component in a [Toaster](/docs/toaster) with a custom render function to overwrite its defaults.
## Available options
```jsx
```
## Add custom content
You can add a **render function to the ToastBar to modify its content**. An object containing The `icon` as well as the `message` are passed into the function.
### Add a dismiss button
In this example we add a basic dismiss button to all toasts, except if the loading one.
```jsx
import { toast, Toaster, ToastBar } from 'react-hot-toast';
{(t) => (
{({ icon, message }) => (
<>
{icon}
{message}
{t.type !== 'loading' && (
)}
>
)}
)}
;
```
================================================
FILE: site/pages/docs/toast.mdx
================================================
import Layout from '../../components/docs-layout';
import toast from 'react-hot-toast';
export const meta = {
title: 'toast() API',
};
# `toast()` API
Call it to create a toast from anywhere, even outside React. Make sure you add the [``](/docs/toaster) component to your app first.
## Available toast options
You can provide `ToastOptions` as the second argument. They will overwrite all options received from [``](/docs/toaster).
```js
toast('Hello World', {
duration: 4000,
position: 'top-center',
// Styling
style: {},
className: '',
// Custom Icon
icon: '👏',
// Change colors of success/error/loading icon
iconTheme: {
primary: '#000',
secondary: '#fff',
},
// Aria
ariaProps: {
role: 'status',
'aria-live': 'polite',
},
// Additional Configuration
removeDelay: 1000,
// Toaster instance
toasterId: 'default',
});
```
## Creating a toast
### Blank
```js
toast('Hello World');
```
The most basic variant. It does not have an icon by default, but you can provide one via the options. If you don't want any default styles, use `toast.custom()` instead.
### Success
```js
toast.success('Successfully created!');
```
Creates a notification with an animated checkmark. It can be themed with the `iconTheme` option.
### Error
```js
toast.error('This is an error!');
```
Creates a notification with an animated error icon. It can be themed with the `iconTheme` option.
### Custom (JSX)
```js
toast.custom(
Hello World
);
```
Creates a custom notification with JSX without default styles.
### Loading
```js
toast.loading('Waiting...');
```
This will create a loading notification. Most likely, you want to update it afterwards. For a friendly alternative, check out `toast.promise()`, which takes care of that automatically.
### Promise
This shorthand is useful for mapping a promise to a toast. It will update automatically when the promise resolves or fails.
#### Simple Usage
```js
const myPromise = fetchData();
toast.promise(myPromise, {
loading: 'Loading',
success: 'Got the data',
error: 'Error when fetching',
});
```
It's recommend to add min-width to your `toast.promise()` calls to **prevent jumps** from different message lengths.
#### Advanced
You can provide a function to the success/error messages to incorporate the result/error of the promise. The third argument are `toastOptions` similiar to [``](/docs/toaster)
```js
toast.promise(
myPromise,
{
loading: 'Loading',
success: (data) => `Successfully saved ${data.name}`,
error: (err) => `This just happened: ${err.toString()}`,
},
{
style: {
minWidth: '250px',
},
success: {
duration: 5000,
icon: '🔥',
},
}
);
```
#### Using an Async Function
You can also provide a function that returns a promise, which will be called automatically.
```js
toast.promise(
async () => {
const { id } = await fetchData1();
await fetchData2(id);
},
{
loading: 'Loading',
success: 'Got the data',
error: 'Error when fetching',
}
);
```
## Default durations
Every type has its own duration. You can overwrite them `duration` with the toast options. This can be done per toast options or globally by the [``](/docs/toaster).
| type | duration |
| --------- | -------- |
| `blank` | 4000 |
| `error` | 4000 |
| `success` | 2000 |
| `custom` | 4000 |
| `loading` | Infinity |
### Dismiss toast programmatically
You can manually dismiss a notification with `toast.dismiss`. Be aware that it triggers the exit animation and does not remove the Toast instantly. Toasts will auto-remove after 1 second by default.
#### Dismiss a single toast
```js
const toastId = toast.loading('Loading...');
// ...
toast.dismiss(toastId);
```
You can dismiss all toasts at once, by leaving out the `toastId`.
#### Dismiss all toasts at once
```js
toast.dismiss();
```
To remove toasts instantly without any animations, use `toast.remove`.
#### Configure remove delay
```js
toast.success('Successfully created!', { removeDelay: 500 });
```
By default, the remove operation is delayed by 1000ms. This is how long a toast should be kept in the DOM after being dismissed. It is used to play the exit animation. This duration (number in milliseconds) can be configured when calling the toast.
Or, for all toasts, using the Toaster like so:
```js
```
#### Remove toasts instantly
```js
toast.remove(toastId);
// or
toast.remove();
```
### Update an existing toast
Each toast call returns a unique id. Use in the toast options to update the existing toast.
```js
const toastId = toast.loading('Loading...');
// ...
toast.success('This worked', {
id: toastId,
});
```
### Prevent duplicate toasts
To prevent duplicates of the same kind, you can provide a unique permanent id.
```js
toast.success('Copied to clipboard!', {
id: 'clipboard',
});
```
### Render JSX custom content
You can provide a React component instead of text. If you don't want any default styles use `toast.custom()` instead.
```jsx
toast(
Custom and bold,
{
icon: ,
}
);
```
You can also supply a function that receives the `Toast` as an argument, giving you access to all properties. This allows you to access the toast id, which can be used to add a dismiss button.
```jsx
toast(
(t) => (
Custom and bold
),
{
icon: ,
}
);
```
export default ({ children }) => {children};
================================================
FILE: site/pages/docs/toaster.mdx
================================================
import Layout from '../../components/docs-layout';
import toast from 'react-hot-toast';
export const meta = {
title: ' API',
};
export default ({ children }) => {children};
# `` API
This component will render all toasts. Alternatively you can create own renderer with the headless [`useToaster()`](/docs/use-toaster) hook.
## Available options
```jsx
```
### `position` Prop
You can change the position of all toasts by modifying supplying `positon` prop.
| Positions | | |
| ----------- | ------------- | ------------ |
| top-left | top-center | top-right |
| bottom-left | bottom-center | bottom-right |
### `reverseOrder` Prop
Toasts spawn at top by default. Set to `true` if you want new toasts at the end.
### `containerClassName` Prop
Add a custom CSS class name to toaster div. Defaults to `undefined`.
### `containerStyle` Prop
Customize the style of toaster div. This can be used to change the offset of all toasts
### `gutter` Prop
Changes the gap between each toast. Defaults to `8`.
### `toasterId` Prop
You can change the toasterId to have a different toaster instance. Learn more about [multiple toasters](/docs/multi-toaster). Defaults to `"default"`.
### `toastOptions` Prop
These will act as default options for all toasts. See [`toast()`](/docs/toast) for all available options.
#### Type specific options
You can change the defaults for a specific type by adding, `success: {}`, `error: {}`, `loading: {}` or `custom: {}`.
## Using a custom render function
You can provide your **own render function** to the Toaster by passing it as children. It will be called for each [Toast](https://github.com/timolins/react-hot-toast/blob/main/src/core/types.ts#L34) allowing you to render any component based on the toast state.
### Minimal example
```jsx
import { Toaster, resolveValue } from 'react-hot-toast';
// In your app
{(t) => (
{resolveValue(t.message, t)}
)}
;
```
`resolveValue()` is needed to resolve all message types: Text, JSX or a function that resolves to JSX.
### Adapting the default [``](/docs/toast-bar)
You can use this API to modify the default ToastBar as well. In this example we overwrite the animation style based on the current state.
```jsx
import { Toaster, ToastBar } from 'react-hot-toast';
{(t) => (
)}
;
```
Check out the [``](/docs/toast-bar) docs for more options.
================================================
FILE: site/pages/docs/use-toaster-store.mdx
================================================
import Layout from '../../components/docs-layout';
import toast from 'react-hot-toast';
export const meta = {
title: 'useToasterStore() API',
};
export default ({ children }) => {children};
# `useToasterStore()` API
This hook gives you access to the internal toaster state. This is the right choice if you need access to the data without wanting to roll your own toaster.
In comparison to [`useToaster()`](/docs/use-toaster) it does not handle pausing or provide handlers for creating your own notification system.
```jsx
import { useToasterStore } from 'react-hot-toast';
const { toasts, pausedAt } = useToasterStore();
```
================================================
FILE: site/pages/docs/use-toaster.mdx
================================================
import Layout from '../../components/docs-layout';
import toast from 'react-hot-toast';
export const meta = {
title: 'useToaster() API',
};
export default ({ children }) => {children};
# `useToaster()` API
The `useToaster()` hook provides a **headless toast management system** for building custom notification UIs. It manages toast state and lifecycle without rendering any components.
It handles pausing on hover, auto-removal, and provides a 1-second removal delay with `visible` flag for smooth animations.
**Alternative**: Use [`useToasterStore()`](/docs/use-toaster-store) if you already have a toaster instance and only need the state.
### Importing
```jsx
import { useToaster } from 'react-hot-toast';
```
You can also import from the headless entry point to exclude UI components:
```jsx
import { useToaster } from 'react-hot-toast/headless';
```
**Note**: [React Hot Toast 2.0](/docs/version-2) includes **custom render functions** for easier custom components.
## API Reference
### Parameters
```tsx
useToaster(
toastOptions?: DefaultToastOptions,
toasterId?: string
)
```
| Parameter | Type | Default | Description |
| -------------- | --------------------- | ----------- | ----------------------------------------------- |
| `toastOptions` | `DefaultToastOptions` | `undefined` | Default options for all toasts in this instance |
| `toasterId` | `string` | `'default'` | Unique identifier for this toaster instance |
### Returns
```tsx
{
toasts: Toast[];
handlers: {
startPause: () => void;
endPause: () => void;
updateHeight: (toastId: string, height: number) => void;
calculateOffset: (toast: Toast, options?: OffsetOptions) => number;
};
}
```
#### `toasts`
Array of all toasts in this toaster instance, including hidden ones for animation purposes.
#### `handlers`
- **`startPause()`**: Pause all toast timers (useful for hover states)
- **`endPause()`**: Resume all toast timers
- **`updateHeight(toastId, height)`**: Update toast height for offset calculations
- **`calculateOffset(toast, options)`**: Calculate vertical offset for toast positioning
## Multiple Toasters
You can create multiple independent toaster instances by providing a unique `toasterId`. See the [Multiple Toasters](/docs/multi-toaster) guide for detailed examples.
```jsx
const sidebar = useToaster({ duration: 5000 }, 'sidebar');
toast('Sidebar notification', { toasterId: 'sidebar' });
```
## Examples
### Basic Implementation
```jsx
import toast, { useToaster } from 'react-hot-toast/headless';
const Notifications = () => {
const { toasts, handlers } = useToaster();
const { startPause, endPause } = handlers;
return (
);
};
```
## Usage with React Native
The headless API works perfectly with React Native. View the [React Native example]() for implementation details.
================================================
FILE: site/pages/docs/version-2.mdx
================================================
import Layout from '../../components/docs-layout';
import toast from 'react-hot-toast';
export const meta = {
title: 'react-hot-toast 2.0 changes',
};
export default ({ children }) => {children};
# What's new in react-hot-toast 2.0
This release is all about **flexibility**. It allows you to create the notification system of your dreams, even simpler. Before we dig deeper into the new APIs, check out what's included in this release:
As well as a many [other improvements and fixes](#changelog).
## Introducing `toast.custom()`
This new function allows you to **render any React component** on the fly. Pass in JSX, and it will add it to the notification stack. There are no default styles applied, giving you complete control.
This API makes it super easy to add [Tailwind UI Notifications](https://tailwindui.com/components/application-ui/overlays/notifications) to your React app.
```jsx
// Minimal Example
toast.custom(
Minimal Example
);
// Tailwind Example
toast.custom((t) => (
Hello TailwindCSS! 👋
));
```
In the example above, we pass in a **function that returns JSX**. This allows us to access the current toast state and toggle between the enter and exit animation.
Instead of CSS keyframe animations, you can use TailwindCSS classes by wrapping it in the [Transition](https://headlessui.dev/react/transition) component from [@headlessui/react](https://headlessui.dev/).
## Better accessibility
The prefers reduced motion is now respected by default. If react-hot-toast detects this setting, it will use fade transitions instead of sliding.
## Smoother exit animation
The exit animation is now less hectic when you have multiple toasts stacked.
## Per toast positioning
From now on, it's possible to have toasts at multiple positions at once. Just add the `position` you want as option when dispatching a toast.
```jsx
toast.success('Always at the bottom', {
position: 'bottom-center',
});
```
## Relative positioning
You can now overwrite the default position of the toaster and place it anywhere you want.
```jsx
```
## Simpler offset styling
There is now a `gutter` option to control the gap between toasts.
```jsx
```
The offset is now controlled by the Toaster and can be changed by overwriting the `top`, `right`, `bottom` and `left` styles.
```jsx
```
## Custom Renderer API
You can now use the [``](/docs/toaster#using-a-custom-render-function) to render your own components. Pass in a function that receives a [Toast](https://github.com/timolins/react-hot-toast/blob/main/src/core/types.ts#L34) as the first argument, allowing you to render whatever you please.
This is a great alternative if you are using [`useToaster()`](/docs/use-toaster) to render create custom notfications.
This API allows us to dynamically react to the current state of your toasts. This can be used to **change the default animations**, add **a custom dismiss button** or render a custom notification, like [TailwindUI Notifications](https://tailwindui.com/components/application-ui/overlays/notifications).
```jsx
import { toast, Toaster, ToastBar } from 'react-hot-toast';
const CustomToaster = () => (
{(t) => (
{({ icon, message }) => (
<>
{icon}
{message}
{t.type !== 'loading' && (
)}
>
)}
)}
);
```
This example adapts the [ToastBar](/docs/toast-bar) with its new render function API. You can read more about the APIs in the [Toaster](/docs/toaster) & [ToastBar](/docs/toast-bar) docs.
## Available now
Get react-hot-toast 2.0 while it's hot. Upgrading from 1.0.0 should be seamless for most users.
```sh
pnpm add react-hot-toast
```
## The future and beyond
React Hot Toast got a lot more flexible with this version, laying the **foundation for future releases**. Thanks to everyone who helped out; much appreciated!
In the next releases, I plan to add the [most requested feature](https://github.com/timolins/react-hot-toast/issues/7): a dismiss button. As well as support for [custom toast types](https://github.com/timolins/react-hot-toast/issues/23).
---
## Changelog
### New
- Easier Customization
- Create your own toast renderer (without useToaster)
- Support for custom render function in Toaster
- Support for custom render function in ToastBar
- `toast.custom()` - Render custom one-off toasts. No default styling will be applied.
- Per toast positioning
- New exit animation
- Change the gutter between toasts with ``
- Support for relative positioning
- Respect reduce motion OS setting
- Create persistent toasts with `duration: Infinity`
### Breaking Changes
- Use the `top`, `right`, `bottom`, `left` to in `containerStyle` to change the offset, instead of margin
- Loading toasts no longer disappear after 30 seconds
- `role` & `ariaLive` got moved into `ariaProps`
- `useToaster()` no longer exposes `visibleToasts`
- No longer expose `dispatch`
================================================
FILE: site/pages/index.tsx
================================================
import { NextSeo } from 'next-seo';
import toast, {
Toaster,
useToasterStore,
ToastPosition,
} from 'react-hot-toast';
import React, { useState } from 'react';
import clsx from 'clsx';
import Link from 'next/link';
import Logo from '../assets/logo.svg';
import Butter1 from '../assets/butter-1.svg';
import Butter2 from '../assets/butter-2.svg';
import GitHub from '../assets/github.svg';
import Checkmark from '../assets/checkmark.svg';
import { ToastExample } from '../components/sections/toast-example';
import { Footer } from '../components/sections/footer';
import { ToasterExample } from '../components/sections/toaster-example';
import { SplitbeeCounter } from '../components/sections/splitbee-counter';
import packageInfo from '../../package.json';
const version = packageInfo.version;
const Feature: React.FC<{ children?: React.ReactNode }> = ({ children }) => (