---
id: "packages/active-ui/alert"
title: "Alert"
description: "A message in the page in a neutral, warning or danger tone, with the announcement left to you."
url: "/packages/active-ui/alert"
locale: "en"
revision: "ae2fe3b641d0dd32"
---

# Alert

An alert is a message that stays in the page: an instruction, a warning about the data shown, the
reason something failed. For a short notice about an action that comes and goes, use a
[toast](/packages/active-ui/toast); for a question that must be answered, an
[alert dialog](/packages/active-ui/alert-dialog).

**Example: Three tones, and an announced failure**

Client: Runs entirely in your browser. Source: `examples/ui/alert.tsx`.

```tsx
// apps/docs/examples/ui/alert.tsx
'use client';

import {useState} from 'react';
import {AlertTriangleIcon, InfoIcon, XCircleIcon} from 'lucide-react';

import {
  Alert,
  AlertAction,
  AlertDescription,
  AlertTitle,
} from '@workspace/active-ui/components/primitives/alert';
import {Button} from '@workspace/active-ui/components/primitives/button';

/**
 * A message in the page, in three tones. The first two are part of the page
 * and carry no role; the third appears after an action and is announced, so
 * it carries `role="alert"`. The tone is the look, the role the announcement:
 * you choose both.
 */
export default function AlertExample() {
  const [failed, setFailed] = useState(false);
  return (
    <div className="flex w-full max-w-lg flex-col gap-4">
      <Alert>
        <InfoIcon aria-hidden />
        <AlertTitle>Statements go out on 1 November</AlertTitle>
        <AlertDescription>
          Changes made after 25 October appear on the next statement.
        </AlertDescription>
      </Alert>
      <Alert variant="warning">
        <AlertTriangleIcon aria-hidden />
        <AlertTitle>Two participants have no address</AlertTitle>
        <AlertDescription>
          They receive their statement in the portal only.
        </AlertDescription>
        <AlertAction>
          <Button variant="outline" size="sm">
            Review
          </Button>
        </AlertAction>
      </Alert>
      <Button
        variant="outline"
        className="self-start"
        onClick={() => setFailed(true)}
        disabled={failed}
      >
        Send the statements
      </Button>
      {failed ? (
        <Alert variant="destructive" role="alert">
          <XCircleIcon aria-hidden />
          <AlertTitle>The statements were not sent</AlertTitle>
          <AlertDescription>
            The mail service did not answer. Nothing was sent; try again in a
            few minutes. (This example always fails.)
          </AlertDescription>
          <AlertAction>
            <Button
              variant="outline"
              size="sm"
              onClick={() => setFailed(false)}
            >
              Try again
            </Button>
          </AlertAction>
        </Alert>
      ) : null}
    </div>
  );
}
```

## Usage

```tsx
import {
  Alert,
  AlertDescription,
  AlertTitle,
} from '@workspace/active-ui/components/primitives/alert';

<Alert variant="warning">
  <AlertTriangleIcon aria-hidden />
  <AlertTitle>Two participants have no address</AlertTitle>
  <AlertDescription>
    They receive their statement in the portal only.
  </AlertDescription>
</Alert>;
```

## Tone and announcement are separate

`variant` sets the look: `default`, `warning` or `destructive`. All three sit on the card colour;
the warning and danger tones colour the title, the icon and the border, with text that reaches AA.

The alert sets **no role**, unlike shadcn/ui's, which made every alert an assertive live region.
Whether a screen reader announces it depends on what happened, not on how it looks, so you choose:

- **no role** for a message that is part of the page when it loads: an instruction, a stored
  failure reason, a status. It is read in its place;
- **`role="status"`** for a change after an action that can wait, such as a warning that appears
  after a choice in a form;
- **`role="alert"`** for a failure after an action that the reader must know now, such as a
  rejected submission, as in the example.

Before adding a role, check whether something else already announces the same: a toast is a live
region itself, and a `FieldError` carries its own `role="alert"`. Two regions read the same text
twice.

## Anatomy

- `Alert`: the frame. An icon as its first child sits in its own column.
- `AlertTitle` and `AlertDescription` (links in it are underlined).
- `AlertAction`: an action in the top right corner.

## What your application provides

- The text, the icon, and the role when the alert should be announced.
- An action when the reader can do something about it.

## API

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `variant` | `"default" \| "destructive" \| "warning" \| null` | no | The tone: `default`, `warning` or `destructive`. It sets the look only; the announcement is the caller's role (see `Alert`). |

### Other parts

**AlertTitle**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |

AlertTitle has no props of its own.

**AlertDescription**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |

AlertDescription has no props of its own.

**AlertAction**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |

AlertAction has no props of its own.

> [!NOTE]
> **Based on shadcn/ui**
>
> This page adapts the Alert documentation of shadcn/ui (MIT licence) to this
> package; see [Third-party notices](/third-party-notices).
