oks-ui

How to use

Alert

Alert surfaces contextual feedback inline with the content it relates to — a validation error under a form, a success message after a save, a warning banner at the top of a page. It renders with role="alert" so assistive technology announces it as soon as it appears, and unlike Toast it never leaves its place in the layout or auto-dismisses on its own.

import { Alert } from "oks-ui";

Feedback after an action

The most common place to reach for Alert is right after something happens — a form submits, a request fails, a background job finishes. Keep a small piece of state for whichever case applies, render the matching Alert conditionally, and pass isClosable with an onClose handler that clears that state so the user can dismiss it once they've read it.

function SaveFeedback() {
  const [status, setStatus] = useState<"success" | "error" | null>(null);

  async function handleSave() {
    try {
      await fetch("/api/profile", { method: "PATCH" });
      setStatus("success");
    } catch {
      setStatus("error");
    }
  }

  return (
    <div className="flex flex-col gap-3">
      {status === "success" && (
        <Alert
          color="success"
          title="Saved"
          description="Your profile changes were saved."
          isClosable
          onClose={() => setStatus(null)}
        />
      )}
      {status === "error" && (
        <Alert
          color="danger"
          title="Couldn't save"
          description="Something went wrong. Try again."
          isClosable
          onClose={() => setStatus(null)}
        />
      )}
      <Button onPress={handleSave} color="primary">Save changes</Button>
    </div>
  );
}

Variant and color together

variant controls density, color controls meaning, and they're independent — pick both for the emphasis a message actually needs. solid (the default) fills the background with the color and reads as the most urgent; soft uses a translucent tint of the color, a good default for messages living inside a form or card where a solid block would compete with the rest of the page; bordered keeps just a colored edge and barely-there background, for messages that should be noticeable but not shout.

The seven color values (default, primary, secondary, info, success, warning, danger) each drive the built-in status icon automatically, so picking a success or danger color doesn't require also picking an icon — Alert already knows which one fits.

<Alert variant="solid" color="danger" title="Failed" description="The upload could not complete." />
<Alert variant="soft" color="warning" title="Heads up" description="You have unsaved changes." />
<Alert variant="bordered" color="info" title="Note" description="This setting applies to new members only." />

Dismissible vs. persistent

isClosable adds a close button (and lets Escape dismiss it while it has focus) — reach for it on transient feedback like a save confirmation, where there's nothing left for the user to do but acknowledge it. Leave it off (the default) for a persistent alert the user needs to actually resolve, like a validation error still attached to an invalid field — closing it wouldn't fix the underlying problem, so removing the escape hatch keeps the message in front of them until the form is valid.

Alert supports both controlled and uncontrolled visibility. Pass isVisible yourself if you're already tracking the state elsewhere; otherwise just mount/unmount the Alert (as in the example above) and let onClose tell you when to unmount it.

Extra content: startContent, actions, endContent

Three optional slots sit around the title/description block for anything an inline text message alone can't cover. startContent renders above the icon/title/description row — useful for a small label or badge. actions renders directly below the description, for a button or two that respond to the alert ("Retry", "Undo", "View details"). endContent renders after actions, for something like a timestamp or a secondary link.

<Alert
  color="danger"
  title="Upload failed"
  description="The file exceeded the 10 MB limit."
  actions={
    <Button size="sm" variant="soft" color="danger" onPress={retry}>
      Try again
    </Button>
  }
  isClosable
  onClose={() => setShowError(false)}
/>

Custom and hidden icons

Every color role has a sensible default icon baked in, so most usage never needs to touch it. When it does: pass icon with any ReactNode to replace it outright, hideIcon to remove the icon (and its wrapper) entirely, or hideIconWrapper to keep the icon but drop the circular background behind it — handy when the icon itself already reads clearly without extra framing.

Accessibility

  • The root element carries role="alert", so screen readers announce new alerts as soon as they mount without the user needing to navigate to them.
  • When isClosable is true, the close button has a built-in aria-label of "Close" and responds to both a click and the Escape key while the alert has focus.
  • Color is never the only signal — pair it with a clear title/description, since color alone doesn't communicate anything to a screen-reader user or anyone with color-vision deficiency.

Props reference

All available props for Alert. See the full component page for an interactive playground.

Props

title

ReactNode

Default:

Alert title.

description

ReactNode

Default:

Alert body content.

icon

ReactNode

Default:

Overrides the default color-derived status icon.

startContent

ReactNode

Default:

Content rendered before the title/description block.

endContent

ReactNode

Default:

Content rendered after the title/description block.

actions

ReactNode

Default:

Action buttons rendered below the description.

Best practices

  • Keep the title short and the description one sentence — Alert is for a quick status update, not an essay.
  • Use isClosable={false} for validation errors that are still attached to an invalid field, so the user resolves the actual problem instead of just dismissing the message.
  • Reach for variant="soft" inside forms and cards, where a solid block of color competes too hard with the surrounding content.
  • Avoid stacking more than two or three Alerts at once — if there are several unrelated issues, consider a single Alert with a list in the description instead.
  • For a message that should slide in, sit outside the document flow, and disappear on its own, use Toast instead — Alert stays inline and never auto-dismisses.
View full API reference for Alert