Feedback
Alert
An inline message about the state of the page or the account, with status variants, an AI variant and room for actions.
npx prodular-ui add alertStatus variants
Tinted fill with a matching border. Pick the variant by consequence, not by mood.
Scheduled maintenance on Sunday
The API will be read only from 02:00 to 02:30 UTC while we migrate the EU region.
Domain verified
billing.halden.io now sends receipts with your brand.
You have used 92% of your API quota
Requests are throttled at 100%. The quota resets on November 1.
Payment failed
We could not charge the Visa ending 4242. Update it by October 28 to keep your workspace active.
import { CircleAlertIcon, CircleCheckIcon, InfoIcon, TriangleAlertIcon,} from "lucide-react"
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
export default function AlertVariants() { return ( <div className="flex w-full max-w-lg flex-col gap-3"> <Alert variant="info" role="status"> <InfoIcon /> <AlertTitle>Scheduled maintenance on Sunday</AlertTitle> <AlertDescription> The API will be read only from 02:00 to 02:30 UTC while we migrate the EU region. </AlertDescription> </Alert> <Alert variant="success" role="status"> <CircleCheckIcon /> <AlertTitle>Domain verified</AlertTitle> <AlertDescription> billing.halden.io now sends receipts with your brand. </AlertDescription> </Alert> <Alert variant="warning"> <TriangleAlertIcon /> <AlertTitle>You have used 92% of your API quota</AlertTitle> <AlertDescription> Requests are throttled at 100%. The quota resets on November 1. </AlertDescription> </Alert> <Alert variant="destructive"> <CircleAlertIcon /> <AlertTitle>Payment failed</AlertTitle> <AlertDescription> We could not charge the Visa ending 4242. Update it by October 28 to keep your workspace active. </AlertDescription> </Alert> </div> )}AI
For insights a model produced. The gradient hairline marks it as generated.
3 accounts look likely to churn this month
Usage at Pinecrest Health, Corvid Labs and Marlow and Finch dropped more than 40% in two weeks. Generated from product analytics.
import { SparklesIcon } from "lucide-react"
import { Alert, AlertActions, AlertDescription, AlertTitle,} from "@/components/ui/alert"import { Button } from "@/components/ui/button"
export default function AlertAi() { return ( <Alert variant="ai" role="status" className="max-w-lg"> <SparklesIcon /> <AlertTitle>3 accounts look likely to churn this month</AlertTitle> <AlertDescription> Usage at Pinecrest Health, Corvid Labs and Marlow and Finch dropped more than 40% in two weeks. Generated from product analytics. </AlertDescription> <AlertActions> <Button size="sm" variant="outline"> Review accounts </Button> <Button size="sm" variant="ghost"> Dismiss </Button> </AlertActions> </Alert> )}With actions
AlertAction pins one control to the top right. AlertActions adds a row of buttons under the text.
Rotate your API key
The production key was created 11 months ago. Keys older than a year stop working on January 1.
Webhook endpoint is failing
28 deliveries to hooks.tidewater.co returned 503 in the last hour.
import { KeyRoundIcon, TriangleAlertIcon, XIcon } from "lucide-react"
import { Alert, AlertAction, AlertActions, AlertDescription, AlertTitle,} from "@/components/ui/alert"import { Button } from "@/components/ui/button"
export default function AlertActionsDemo() { return ( <div className="flex w-full max-w-lg flex-col gap-3"> <Alert role="status"> <KeyRoundIcon /> <AlertTitle>Rotate your API key</AlertTitle> <AlertDescription> The production key was created 11 months ago. Keys older than a year stop working on January 1. </AlertDescription> <AlertAction> <Button variant="ghost" size="icon-sm" aria-label="Dismiss"> <XIcon /> </Button> </AlertAction> </Alert> <Alert variant="warning"> <TriangleAlertIcon /> <AlertTitle>Webhook endpoint is failing</AlertTitle> <AlertDescription> 28 deliveries to hooks.tidewater.co returned 503 in the last hour. </AlertDescription> <AlertActions> <Button size="sm" variant="outline"> View deliveries </Button> <Button size="sm" variant="ghost"> Pause endpoint </Button> </AlertActions> </Alert> </div> )}Anatomy
<Alert variant="warning"> <TriangleAlertIcon /> <AlertTitle>Webhook endpoint is failing</AlertTitle> <AlertDescription>28 deliveries returned 503.</AlertDescription> <AlertActions> <Button size="sm" variant="outline">View deliveries</Button> </AlertActions></Alert>Guidance
Use it when
- Tell people about something that affects the page they are on: a failed payment, a quota, maintenance.
- Place it at the top of the content it is about, not in a corner of the screen.
- Use ai for a model generated insight that people should review.
Avoid
- Confirming an action the person just took. Use a Toast.
- Stacking more than two alerts. Combine them or move the rest to a notifications view.
- Alerts inside cards. An alert is its own surface. Put it above the card instead.
Rules for AI agents
Published in llms-full.txt and the registry, so coding agents follow them when they build with this component.
- Choose the variant by consequence: destructive when something failed or will stop working, warning when action is needed soon, success to confirm a lasting state, info for neutral notices, default for tips.
- Always include a lucide icon as the first child so the layout aligns: InfoIcon, CircleCheckIcon, TriangleAlertIcon, CircleAlertIcon, SparklesIcon for ai.
- Write AlertTitle as the outcome in one line. Put the reason and the next step in AlertDescription.
- The default role is alert, which interrupts screen readers. Pass role="status" for info, success and ai alerts that are not urgent.
- Use AlertAction for a dismiss button (Button variant="ghost" size="icon-sm" with aria-label). Use AlertActions for up to two sm buttons, outline first.
- Use variant="ai" only for content a model generated, and say so in the description.
API
Alert
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "default" | "info" | "success" | "warning" | "destructive" | "ai" | "default" | Color and border. Also set as data-variant. |
| role | "alert" | "status" | "alert" | Use status for messages that should not interrupt. |
AlertAction
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | One control pinned to the top right, usually a dismiss button. |
AlertActions
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | A row of buttons under the description. |