# 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.

> This component is only available in **AdminKit PRO**. [Learn more](/pricing/#react).

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](/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:

```html
<button type="button" class="btn btn-primary" id="toastSaveButton">Save changes</button>

<script>
document.getElementById("toastSaveButton").addEventListener("click", function () {
  showToast({
    message: "Your changes have been saved.",
    type: "success",
    dismissible: true
  });
});
</script>
```
```tsx code
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:

| Option | Type | Default | Description |
| --- | --- | --- | --- |
| `message` | `ReactNode` | | The content of `.toast-body` |
| `type` | `"default" \| "primary" \| "secondary" \| "success" \| "info" \| "warning" \| "danger"` | `"default"` | The background color (`text-bg-*`); `"default"` is primary |
| `duration` | `number` | `5000` | Milliseconds before it hides; `0` keeps it until it is closed |
| `dismissible` | `boolean` | `false` | Adds 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:

```html
<button type="button" class="btn btn-info me-2" id="toastTopLeft">Top left</button>
<button type="button" class="btn btn-warning me-2" id="toastTopCenter">Top center</button>
<button type="button" class="btn btn-danger" id="toastBottomRight">Bottom right</button>

<script>
document.getElementById("toastTopLeft").addEventListener("click", function () {
  showToast({ message: "3 new comments.", type: "info", position: { x: "left", y: "top" } });
});
document.getElementById("toastTopCenter").addEventListener("click", function () {
  showToast({ message: "Your trial ends in 2 days.", type: "warning", position: { x: "center", y: "top" } });
});
document.getElementById("toastBottomRight").addEventListener("click", function () {
  showToast({ message: "The upload failed.", type: "danger", position: { x: "right", y: "bottom" } });
});
</script>
```
```tsx code
<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:

```tsx
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:

```html
<button type="button" class="btn btn-primary" id="toastExportButton">Export report</button>

<div class="toast mt-3" id="toastExport" role="alert" aria-live="assertive" aria-atomic="true">
  <div class="toast-header">
    <strong class="me-auto">Reports</strong>
    <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
  </div>
  <div class="toast-body">The export has started. You get an email when it is ready.</div>
</div>

<script>
document.getElementById("toastExportButton").addEventListener("click", function () {
  bootstrap.Toast.getOrCreateInstance(document.getElementById("toastExport")).show();
});
</script>
```
```tsx code
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>
    </>
  );
}
```

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `show` | `boolean` | | Whether the toast is shown |
| `onClose` | `() => void` | | Called when the autohide delay has passed; set `show` to false here |
| `onExited` | `() => void` | | Called once the toast has faded out |
| `autohide` | `boolean` | `true` | Hides the toast after `delay` |
| `delay` | `number` | `5000` | Milliseconds from the end of the fade-in to `onClose` |
| `className` | `string` | | Extra 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 class="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"`.

## Related

- [Next.js toast notifications](/nextjs/docs/components/toasts/): the same component in AdminKit for Next.js
- [Bootstrap 5 toasts](/bootstrap/docs/components/toasts/): the toasts and `showToast()` of the HTML version
- [Alerts](/react/docs/components/alerts/): messages that stay in the page
- [Notifications demo](https://react-demo.adminkit.io/notifications)

---

Canonical HTML page: https://adminkit.io/react/docs/components/toasts/

Site overview for agents: https://adminkit.io/llms.txt (expanded: https://adminkit.io/llms-full.txt) · Documentation: https://adminkit.io/bootstrap/docs/ · Questions: support@adminkit.io
