---
id: "packages/active-ui/notice-screen"
title: "NoticeScreen and ErrorScreen"
description: "A screen that carries one message - a refusal, a page that does not exist, or an error with its reference."
url: "/packages/active-ui/notice-screen"
locale: "en"
revision: "57de8447a8327e36"
---

# NoticeScreen and ErrorScreen

`NoticeScreen` fills the viewport with one centred card: an icon, a title, a line of explanation,
the ways forward and a footer line. Use it for a page the reader cannot see: no access, not
found, maintenance. `ErrorScreen` is the same card for an error that hit a whole page, with the
icon in the destructive tone and the error's reference as its footer.

**Example: A refusal and an error**

Client: Runs entirely in your browser. Source: `examples/ui/notice-screen.tsx`.

```tsx
// apps/docs/examples/ui/notice-screen.tsx
'use client';

import {useState} from 'react';
import {LockIcon} from 'lucide-react';

import {ErrorScreen} from '@workspace/active-ui/components/composed/error-screen';
import {NoticeScreen} from '@workspace/active-ui/components/composed/notice-screen';
import {Button} from '@workspace/active-ui/components/primitives/button';
import {
  ToggleGroup,
  ToggleGroupItem,
} from '@workspace/active-ui/components/primitives/toggle-group';

/**
 * Two screens that each carry one message: a refusal on the neutral notice
 * screen, and an error on the error screen with its reference. Both fill the
 * viewport in an application; here `className` bounds them to the frame.
 * The buttons do nothing.
 */
export default function NoticeScreenExample() {
  const [screen, setScreen] = useState('notice');
  return (
    <div className="grid w-full gap-4">
      <ToggleGroup
        aria-label="Screen"
        variant="outline"
        value={[screen]}
        onValueChange={(next) => next[0] && setScreen(next[0])}
      >
        <ToggleGroupItem value="notice">NoticeScreen</ToggleGroupItem>
        <ToggleGroupItem value="error">ErrorScreen</ToggleGroupItem>
      </ToggleGroup>
      <div className="overflow-hidden rounded-md border">
        {screen === 'notice' ? (
          <NoticeScreen
            className="min-h-0 py-10"
            icon={<LockIcon />}
            title="No access"
            description="You need the administrator role to open this page."
            actions={<Button className="w-full">Back to the overview</Button>}
          />
        ) : (
          <ErrorScreen
            className="min-h-0 py-10"
            title="Something went wrong"
            description="The page could not be loaded. Try again in a moment."
            actions={
              <>
                <Button className="w-full">Try again</Button>
                <Button variant="outline" className="w-full">
                  Back to the overview
                </Button>
              </>
            }
            referenceLabel="Reference:"
            reference="ERR-a1b2c3d4"
          />
        )}
      </div>
    </div>
  );
}
```

## What the composition adds

- **One stable card** without an entrance animation.
- **The icon is decoration**: the screen hides it from assistive technology and sizes and colours
  it; `tone` is `neutral` or `destructive`.
- **Slots, not rules**: `actions` takes your buttons or links, stacked; `footer` takes a line such
  as a reference. `ErrorScreen` fills the footer from `reference` and `referenceLabel`.

The screens catch nothing, log nothing and know no status code: which screen appears, its text and
what the actions do are yours. For an error in one area of a page, use an
[Alert](/packages/active-ui/alert) or an [ErrorBoundary](/packages/active-ui/error-boundary) around
that area.

## Usage

```tsx
import {ErrorScreen} from '@workspace/active-ui/components/composed/error-screen';

<ErrorScreen
  title="Something went wrong"
  description="The page could not be loaded."
  actions={<Button className="w-full">Try again</Button>}
  referenceLabel="Reference:"
  reference={reference}
/>;
```

## What your application provides

- The title, description and actions, translated; buttons at full width (`className="w-full"`).
- The reference of an error: the screen shows it, it does not make one.
- The height, when the screen should not fill the viewport (`className`, as in the example).

## Accessibility

- The title is the screen's `<h1>`, and the announcement: there is no live region, because the
  screen arrives with the page.
- Focus is not moved, so a screen reader starts at the top and reads the title first.
- The example shows a second `<h1>` on this documentation page; in an application the screen is the
  page.

## API

### NoticeScreen

**NoticeScreen**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `icon` | `ReactNode` | yes | The icon in the circle above the heading.  **Decorative**, and the shell handles that itself: the circle carries `aria-hidden`, so the icon and everything around it is invisible to a screen reader. The caller therefore passes a bare icon and no `aria-hidden`, `aria-label` or `role` of its own. The meaning is in {@link title}; a second accessible name would read it out twice.  The shell also sets the size (`size-6`) and the colour (via {@link tone}, which the icon inherits as `currentColor`). An icon that brings its own `size-*` keeps it. |
| `title` | `string` | yes | The heading of the screen. Renders as `<h1>`; there is exactly one. |
| `actions` | `ReactNode` | no | The actions, from the caller. Stacked vertically; the buttons themselves are full width because the caller passes them that way.  A slot and not `href`/`onRetry`/`onHome` props: which way back exists differs per context, and that choice belongs to whoever knows the context. This shell knows no router and must not know one. |
| `className` | `string` | no | The shell is normally `min-h-dvh`. This prop is where a caller overrides that height, for example to show the screen in a bounded area (`min-h-full` in a lab case or a variant preview). |
| `description` | `ReactNode` | no | A line of explanation below the heading. Inline content; omit rather than pass empty. |
| `footer` | `ReactNode` | no | A separated footer line below the actions, for example a reference.  A slot and not a `reference`/`referenceLabel` pair: that pair is the reference chain of an outage and a denial and therefore semantics of the layer above. A 404 has none, because it is not logged. The shell knows nothing of that and only provides the separator line and the space. |
| `tone` | `NoticeScreenTone` | no | Which of the two tones the icon surface gets. Defaults to neutral: most notices do not report an outage. |

**NoticeScreenTone**

```ts
type NoticeScreenTone = 'neutral' | 'destructive';
```

The two presentation tones that actually exist, measured across the three
consumers: an outage is destructive, a denial and a 404 are neutral.

Deliberately no `warning`, `success` or `info` added "for later". A tone
nobody sets is a promise nobody has kept, and it would moreover suggest that
this component has a semantic axis. If a third real tone appears, that is the
moment to add it.

The names follow the colour tokens (`--destructive`) and not the five tones
of `StatusBadge`: this is about an icon surface and an icon, and those
carry the base colour, not the text variant.

**NoticeScreenProps**

```ts
interface NoticeScreenProps {
  icon: ReactNode;
  tone?: NoticeScreenTone;
  title: string;
  description?: ReactNode;
  actions?: ReactNode;
  footer?: ReactNode;
  className?: string;
}
```

### ErrorScreen

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `title` | `string` | yes | The screen's heading. Renders as `<h1>`; there is exactly one. |
| `actions` | `ReactNode` | no | The recovery actions, from the caller. Stacked vertically at full width.  A slot and not `onRetry`/`onBack`/`onHome` props: which way back exists differs per context, and that choice belongs to whoever knows the context. |
| `className` | `string` | no | Classes for the screen. |
| `description` | `string` | no | One line of explanation below the heading. |
| `reference` | `string` | no | The full reference text as it should appear on screen, including any prefix (for example `ERR-a1b2c3d4`).  The component generates no identity; it shows one. |
| `referenceLabel` | `string` | no | The label before the reference, for example `Reference:`. |

**ErrorScreenProps**

```ts
interface ErrorScreenProps {
  title: string;
  description?: string;
  actions?: ReactNode;
  reference?: string;
  referenceLabel?: string;
  className?: string;
}
```
