Skip to content

Toast — Vanilla JS

Terminal window
npm install @fluix-ui/vanilla @fluix-ui/css
import { createToaster, fluix } from "@fluix-ui/vanilla";
import "@fluix-ui/css";
// Initialize once — this creates the toast viewport in the DOM
createToaster({ position: "top-right" });
// Fire toasts from anywhere
document.getElementById("save-btn")?.addEventListener("click", () => {
fluix.success({ title: "Saved!" });
});

Call createToaster() once to mount the viewport. Then use the fluix API from anywhere.

createToaster({
position: "top-right",
layout: "stack",
offset: 24,
defaults: {
theme: "dark",
duration: 6000,
roundness: 16,
},
});
OptionTypeDefaultDescription
positionFluixPosition"top-right"Default viewport position
layout"stack" | "notch""stack"Layout mode
offsetnumber | string | objectViewport offset
defaultsPartial<FluixToastOptions>Default toast options

Call fluix.success() from any event listener, callback, or global script. No framework reactivity — just plain DOM events and the fluix singleton:

import { fluix } from "@fluix-ui/vanilla";
document.querySelector("#settings-form")?.addEventListener("submit", async (e) => {
e.preventDefault();
await saveSettings(new FormData(e.target as HTMLFormElement));
fluix.success({
title: "Settings saved",
description: "Your preferences have been updated.",
duration: 5000,
theme: "dark",
roundness: 20,
icon: "",
});
});

The theme option accepts any string — "light", "dark", or a custom name you define in CSS. See Theming for details.

Wrap any Promise to show a loading toast that transitions to success or error. Works with fetch, XMLHttpRequest, or any async operation:

import { fluix } from "@fluix-ui/vanilla";
document.querySelector("#refresh-btn")?.addEventListener("click", () => {
fluix.promise(
fetch("/api/users").then((r) => r.json()),
{
loading: { title: "Loading users..." },
success: (users) => ({
title: "Users loaded",
description: `Found ${users.length} users`,
}),
error: (err) => ({
title: "Failed to load",
description: err.message,
}),
}
);
});

Show a toast with an undo action — useful after destructive operations. Attach it to any DOM event:

import { fluix } from "@fluix-ui/vanilla";
function handleDelete(itemId: string, itemName: string) {
deleteItem(itemId);
fluix.action({
title: "Item deleted",
description: `"${itemName}" has been removed.`,
button: {
title: "Undo",
onClick: () => {
restoreItem(itemId);
fluix.success({ title: "Restored!" });
},
},
});
}

The vanilla package can also be loaded via CDN for use without a bundler:

<link rel="stylesheet" href="https://unpkg.com/@fluix-ui/css/dist/fluix.css" />
<script src="https://unpkg.com/@fluix-ui/vanilla/dist/index.iife.js"></script>
<script>
const { createToaster, fluix } = window.Fluix;
createToaster({ position: "top-right" });
document.getElementById("btn").addEventListener("click", () => {
fluix.success({ title: "Saved!" });
});
</script>

The vanilla adapter directly manages DOM elements using the Fluix core engine. createToaster() mounts a position: fixed viewport element to the document body with ARIA live regions for accessibility.

Unlike React/Vue/Svelte adapters that bridge framework reactivity, the vanilla adapter subscribes to the core store and applies DOM updates imperatively. This makes it suitable for server-rendered pages, WordPress sites, static HTML, or any environment where a JavaScript framework is not available.

The fluix singleton is available globally after importing the package. You can call it from inline event handlers, HTMX responses, Alpine.js expressions, or any JavaScript context.