Toast Component

The Toast component is a lightweight, react-hot-toast-style notification system. Call toast() from anywhere — no hook required — to trigger success, error, warning, info, or loading notifications, each with distinct styling and icons for clear visual communication.

Built around a global store rather than React context, so toast() works from event handlers, API clients, and utility files alike. Includes auto-dismiss, manual dismissal, toast.promise() for async flows, and configurable stack position — making it ideal for async actions, system alerts, and user feedback flows.

What It Does

Import Anywhere: toast() is a standalone function — call it outside components, no hook required.
Async-First: toast.promise() turns a loading toast into success/error automatically.
Five Types: Built-in support for success, error, warning, info, and loading states.
Configurable Position: Anchor the stack to any corner or edge-center.
Auto Dismiss: Toasts close automatically with configurable duration; loading toasts persist until resolved.
Manual Control: Close individually (by id) or clear all programmatically.
Accessible: Proper ARIA live-region and role semantics (errors interrupt, everything else waits).

Import Component From Library

tsx
1import { toast, ToastProvider } from "@neuctra/ui";
2// Prefer a hook instead? useToast() returns the identical toast/dismiss.
3// import { useToast, ToastProvider } from "@neuctra/ui";

Import Component From Library

toast is a standalone function — import it and call it from anywhere: event handlers, API clients, utility files. No hook, no component wrapper required at the call site (only <ToastProvider> needs to be mounted once, to render the toasts — see Setup below).

javascript
1import { toast, ToastProvider } from "@neuctra/ui";

Basic Usage Code

Call toast() directly — this is the whole API for the simple case.

jsx
1import { toast } from '@neuctra/ui';
2
3function BasicExample() {
4  return (
5    <button onClick={() => toast('Hello, this is a toast notification!')}>
6      Show Toast
7    </button>
8  );
9}

Setup

ToastProvider renders the toast viewport — mount it once near your app root, the same way you'd mount a single <Toaster /> in react-hot-toast. It doesn't wrap your app in a context you need to opt into: toast() works even in files that never import React, as long as a ToastProvider is mounted somewhere in the tree to actually render the notifications.

jsx
1import { ToastProvider } from "@neuctra/ui";
2
3export default function App({ Component, pageProps }) {
4  return (
5    <ToastProvider>
6      <Component {...pageProps} />
7    </ToastProvider>
8  );
9}

How it Works

Toasts live in a small module-level store, not React context — the same architecture react-hot-toast uses internally. That's what makes toast() callable from anywhere: <ToastProvider> just subscribes to that store and renders whatever's in it.

  • toast() accepts either a simple string or a structured object, and always returns the toast's id.
  • Shorthand methods: toast.success(), toast.error(), toast.warning(), toast.info(), toast.loading().
  • toast.promise() turns a loading toast into success/error automatically once a promise settles.
  • Toasts auto-dismiss after a default duration (4s), configurable per toast. loading toasts persist (duration: 0) until you resolve or dismiss them.
  • Pass the same id back into a later toast() call to update a toast in place instead of stacking a new one — this is exactly what toast.promise() does under the hood.
  • Users can close toasts via the close button; if you also use useToast(), it returns the identical global toast/dismiss — both APIs stay in sync.

Template Buttons

Pre-built button examples for quickly triggering different toast types. These are useful for testing, prototyping, or copying into real UI flows.

Loading & Promises

The signature react-hot-toast pattern: show a spinner toast for an async action, then let it morph into success or error automatically — no manual dismiss-and-replace bookkeeping.

For finer control, drive the same in-place update manually with toast.loading() and a matched id:

jsx
1const id = toast.loading("Uploading file...");
2
3try {
4  await uploadFile(file);
5  toast.success("File uploaded!", { id });
6} catch {
7  toast.error("Upload failed.", { id });
8}

String Shortcut

Passing a string is the quickest way to display a toast. The string is automatically used as the description, making it perfect for simple, one-line notifications.

Use this when you don't need titles, types, or advanced customization.

jsx
1toast("This is a notification message.");

Shorthand Methods

Use built-in helper methods for common notification types. These methods automatically apply styling, icons, and semantic meaning.

jsx
1toast.success("Saved successfully!");
2toast.error("Something went wrong!");
3toast.warning("Be careful!");
4toast.info("Some information");
5toast.loading("Working on it...");

Position

Set where the toast stack anchors on ToastProvider. Defaults to "bottom-right".

jsx
1<ToastProvider position="top-right">
2  <App />
3</ToastProvider>

Options: top-left, top-center, top-right, bottom-left, bottom-center, bottom-right.

Variants

variant controls surface emphasis, independent of type (success/error/warning/info/loading). The default, "light", is a clean neutral card with only the icon carrying color — matching react-hot-toast's look. "soft" and "dark" are opt-in for when the whole toast should read as its status at a glance.

Customization

Toasts are fully customizable using className and style overrides, down to individual sections like title, description, and icon — and icon lets you swap in any custom node in place of the default type icon (pass icon: null to render no icon at all).

When to Use Each Variant

  • light (default): Everyday feedback — the clean, neutral look that fits most apps out of the box.
  • soft: When the status itself is the point — subtle tinted feedback, background updates.
  • dark: High emphasis alerts, critical actions, or important system messages.

Advanced Usage

For full control, pass an object to toast(). This allows you to define title, description, type, and duration for each notification.

jsx
1toast({
2  type: "success",
3  title: "Success!",
4  description: "Your changes have been saved.",
5  duration: 5000,
6});

Dismiss Control

Every toast() call returns the toast's id — capture it to dismiss that specific toast later, or call toast.dismiss() with no arguments to clear everything.

jsx
1import { toast } from "@neuctra/ui";
2
3const id = toast.success("Saved!", { description: "Will close automatically." });
4
5// dismiss that specific toast early
6toast.dismiss(id);
7
8// clear all toasts
9toast.dismiss();

If you're using the hook instead, useToast() exposes the identical function as dismiss: const { toast, dismiss } = useToast();

Shorthand with Options

Combine shorthand methods with additional options for more expressive notifications while keeping your code clean.

jsx
1toast.success("Saved!", {
2  description: "Your data is safe",
3  duration: 6000,
4});

Common Mistakes

toast('Hello') with no <ToastProvider> mounted anywhere

This no longer throws — the call succeeds, but nothing renders. Mount ToastProvider once near your app root so there's somewhere for toasts to show up.

<ToastProvider> mounted more than once

Every provider renders the same global toast list — mounting two shows every toast twice, the same caveat react-hot-toast's <Toaster /> has.

toast({ duration: "5000" })

Duration must be a number (milliseconds), not a string.

<ToastProvider><App /></ToastProvider>

Mounted once, near the root — correct setup.

Pro Tips

  • Reach for toast.promise() for any async action instead of manually pairing a loading toast with a follow-up dismiss — one call, no id bookkeeping.
  • Use toast.success() for positive feedback after user actions.
  • Keep messages short — toasts should be quick and non-blocking.
  • Use duration: 0 for critical alerts that require manual dismissal.
  • Prefer title + description for complex messages instead of long text.
  • Avoid overusing toasts — too many can overwhelm users.
  • Use error toasts for failures, but consider modals for destructive confirmations.

Frequently Asked Questions

How do I install and import the Toast component?

Install the @neuctra/ui package, then import it with: import { Toast } from "@neuctra/ui";

What variants and sizes does Toast support?

Toast supports variants: light, soft, dark. Use the variant and size props to switch between them, or pass a className to layer on custom Tailwind CSS classes.

Is the Toast component accessible?

Toast is built with semantic HTML and standard ARIA attributes, and supports keyboard navigation and focus states out of the box, so it works well with screen readers and keyboard-only users.

Built with React, Tailwind CSS & TypeScript.