React-hot-toast
lastmod 2024-01-31created 2024-01-314 edits
The Best React Notifications in Town
Simple usage
Install package: It weighs less than 5kb
Add Toaster to your app. Make sure it's placed at the top
| Tip |
| For NextJS, it can be placed in the Top-Level Server Side Component Layout. In my case, at the end of the Top Level <body>, I added it the way you would add a <Script>. |
Start toasting! Call it from anywhere
Tailwind Custom example
Following the example on the official website, the pop-up animation doesn't appear. So you need to add a tailwind theme extension to the tailwind.config.js file as below:
/** @type {import('tailwindcss').Config} */
module.exports = {
...
theme: {
extend: {
animation: {
enter: 'enter 200ms ease-out',
'slide-in': 'slide-in 1.2s cubic-bezier(.41,.73,.51,1.02)',
leave: 'leave 150ms ease-in forwards',
},
keyframes: {
enter: {
'0%': {transform: 'scale(0.9)', opacity: 0},
'100%': {transform: 'scale(1)', opacity: 1},
},
leave: {
'0%': {transform: 'scale(1)', opacity: 1},
'100%': {transform: 'scale(0.9)', opacity: 0},
},
'slide-in': {
'0%': {transform: 'translateY(-100%)'},
'100%': {transform: 'translateY(0)'},
},
},
},
},
...
};
Button Component TypeScript:
'use client';
import type {HTMLAttributes, PropsWithChildren} from 'react';
import toast from 'react-hot-toast';
import {CheckmarkIcon, ErrorIcon} from 'react-hot-toast';
interface CopyUrlButtonProps
extends PropsWithChildren<HTMLAttributes<HTMLButtonElement>> {
successLabel?: string;
errorLabel?: string;
}
export default function CopyUrlButton(props: CopyUrlButtonProps) {
const {successLabel, errorLabel, children, ...attrs} = props;
const handlerClick = async () => {
try {
await navigator.clipboard.writeText(window.location.href);
if (successLabel) {
toast.custom(t => {
return (
<div
className={`${
t.visible ? 'animate-enter' : 'animate-leave'
} max-w-md w-full pointer-events-auto alert alert-success hover:cursor-pointer`}
onClick={() => toast.dismiss(t.id)}
>
<CheckmarkIcon />
<p className="text-base-content">{successLabel}</p>
</div>
);
});
}
} catch (e) {
if (errorLabel) {
toast.custom(t => {
return (
<div
className={`${
t.visible ? 'animate-enter' : 'animate-leave'
} max-w-md w-full pointer-events-auto alert alert-error hover:cursor-pointer`}
onClick={() => toast.dismiss(t.id)}
>
<ErrorIcon />
<p>{errorLabel}</p>
</div>
);
});
}
}
};
return (
<button type="button" role="button" onClick={handlerClick} {...attrs}>
{children}
</button>
);
}
See also
- React
- Toast