AdminKitDocs
Components

React Bootstrap Toasts

React Bootstrap toast notifications: call useToast() from any component to show a colored toast in a corner of the window, or place a single Toast yourself.

Pro

This component is only available in AdminKit PRO. Learn more.

A toast is a short message that appears in a corner of the window and hides itself after a few seconds. Use it to confirm something the user just did, such as saving a form, without interrupting them.

To show one, call the useToast() hook from any component. For a toast you place yourself, there is the Toast component. Both use Bootstrap's toast styles without Bootstrap's JavaScript. Toasts are part of the PRO version of AdminKit for React. The code is in src/components/bootstrap/toast.tsx.

Behind the hook sits ToastProvider, which renders the toasts that useToast() shows. It is already set up: it wraps the routes in src/app.tsx, inside the BrowserRouter. So every page can use the hook, in both the dashboard and the auth layout.

Example

useToast() gives you a showToast function. Each call adds a toast. It fades in, hides itself after 5 seconds and is then removed:

import { useToast } from "@/components/bootstrap/toast";

export function SaveButton() {
  const showToast = useToast();

  return (
    <button
      type="button"
      className="btn btn-primary"
      onClick={() =>
        showToast({
          message: "Your changes have been saved.",
          type: "success",
          dismissible: true,
        })
      }
    >
      Save changes
    </button>
  );
}

useToast() throws an error outside ToastProvider. If you replace src/app.tsx with your own setup, keep ToastProvider around your routes.

Options

showToast() takes one object:

OptionTypeDefaultDescription
messageReactNodeThe content of .toast-body
type"default" | "primary" | "secondary" | "success" | "info" | "warning" | "danger""default"The background color (text-bg-*); "default" is primary
durationnumber5000Milliseconds before it hides; 0 keeps it until it is closed
dismissiblebooleanfalseAdds a close button
position{ x: "left" | "center" | "right"; y: "top" | "bottom" }{ x: "right", y: "top" }The corner or edge of the window

Toasts with the same position stack in one fixed .toast-container. The close button is white, except on warning and info, which have dark text.

Colors and positions

Pick a color that matches the message, and a position that keeps the toast out of the way of your layout:

<button
  type="button"
  className="btn btn-info me-2"
  onClick={() =>
    showToast({ message: "3 new comments.", type: "info", position: { x: "left", y: "top" } })
  }
>
  Top left
</button>
<button
  type="button"
  className="btn btn-warning me-2"
  onClick={() =>
    showToast({ message: "Your trial ends in 2 days.", type: "warning", position: { x: "center", y: "top" } })
  }
>
  Top center
</button>
<button
  type="button"
  className="btn btn-danger"
  onClick={() =>
    showToast({ message: "The upload failed.", type: "danger", position: { x: "right", y: "bottom" } })
  }
>
  Bottom right
</button>

showToast does not change between renders, so you can call it after a request or in an effect. For an error the user must read, keep the toast open with duration: 0 and let them close it:

async function save(data: FormData) {
  const response = await fetch("/api/profile", { method: "POST", body: data });
  if (response.ok) {
    showToast({ message: "Profile saved.", type: "success" });
  } else {
    showToast({ message: "The profile could not be saved.", type: "danger", duration: 0, dismissible: true });
  }
}

A single toast

Sometimes you want more control than showToast() gives: a toast with a header, or one in a spot you choose. Toast is one Bootstrap toast with its fade transition, and the parent holds the open state:

import { useCallback, useState } from "react";
import { CloseButton } from "@/components/bootstrap/close-button";
import { Toast } from "@/components/bootstrap/toast";

export function ExportReport() {
  const [show, setShow] = useState(false);
  const close = useCallback(() => setShow(false), []);

  return (
    <>
      <button type="button" className="btn btn-primary" onClick={() => setShow(true)}>
        Export report
      </button>
      <Toast show={show} onClose={close} className="mt-3">
        <div className="toast-header">
          <strong className="me-auto">Reports</strong>
          <CloseButton onClick={close} />
        </div>
        <div className="toast-body">The export has started. You get an email when it is ready.</div>
      </Toast>
    </>
  );
}
PropTypeDefaultDescription
showbooleanWhether the toast is shown
onClose() => voidCalled when the autohide delay has passed; set show to false here
onExited() => voidCalled once the toast has faded out
autohidebooleantrueHides the toast after delay
delaynumber5000Milliseconds from the end of the fade-in to onClose
classNamestringExtra classes for .toast

The delay starts again whenever onClose changes. Pass a stable function, wrapped in useCallback as above. To pin the toast to a corner, put it in a <div className="toast-container position-fixed top-0 end-0 p-3">.

Accessibility

  • Every toast has role="alert", aria-live="assertive" and aria-atomic="true", so screen readers read it out as soon as it appears. Keep the message short.
  • A toast does not take the focus. Do not put the only way to do something in a toast that hides itself: use duration: 0 with dismissible: true, or a modal.
  • The close button is CloseButton, with aria-label="Close".

Last updated on

On this page