Lightweight, framework-free toast notifications
toast.success("Saved!", "Your changes have been saved.");
toast.error("Error!", "Something went wrong.");
toast.success("Saved!");
toast.info("Title", "With a description body.");
toast.info("Important Notification", "This is a longer message that demonstrates wrapping...");
toast.show({ title: "Quick", body: "Disappears in 2s", autoClose: 2000 });
toast.show({ title: "Persistent", autoClose: false });
const id = toast.loading("Uploading...", "0%");
let progress = 0;
const interval = setInterval(() => {
progress += 10;
toast.update(id, { body: `${progress}%`, progress });
if (progress >= 100) {
clearInterval(interval);
toast.update(id, {
type: "success",
title: "Complete!",
autoClose: 3000,
});
}
}, 300);
toast.show({
title: "Downloading",
autoClose: 10000,
showProgress: true,
});
const data = await toast.promise(fetchData(), {
loading: { title: "Loading..." },
success: (data) => ({ title: "Loaded!", body: `Found ${data.count} items` }),
error: (err) => ({ title: "Failed", body: err.message }),
});
Click "Network Error" multiple times — it updates the existing toast instead of creating new ones.
toast.show({
title: "Network Error",
dedupeKey: "network-error",
});
Creates a manager with maxToasts: 3 — extra toasts queue
up and promote as others dismiss.
const manager = createThemtfy({
maxToasts: 3,
maxQueue: 20,
});
manager.clearQueue();
toast.show({
title: "Item deleted",
action: { label: "Undo", onClick: () => restore() },
});
toast.show({
title: "Published",
action: { label: "View post", href: "#published" },
});
toast.configure({ theme: "dark" }); // or "light" / "system"
toast.configure({
defaults: { position: "top-left", autoClose: 3000 },
maxToasts: 3,
});
Notification rendered
Update applied
Logical dismissal began
Cleanup completed
const unsubscribe = toast.on("dismiss", (event) => {
console.log(event.id, event.reason);
});
unsubscribe();
const id = toast.show({ title: "Hello" });
toast.update(id, { title: "Updated!" });
toast.dismiss(id);
const state = toast.get(id);
const all = toast.getAll();
const notifications = createThemtfy({
maxToasts: 2,
defaults: { position: "center-center" },
theme: "dark",
});
notifications.destroy();
toast.show({
title: "Custom",
backgroundColor: "#1a1a2e",
textColor: "#fff",
icon: false,
});
Toasts use role="status"/aria-live="polite"
(or alert/assertive for errors), the close
button is keyboard-operable (Tab → Enter/Space), decorative icons are
hidden from screen readers, and clicking the toast body never
dismisses.