React Alert Examples — Variants, Icons, Dismissible
Copy-paste React Alert examples — four variants, custom icons, dismissible pattern with state, and rendering alerts from an array. Drivn component library.
Alerts are how your React UI speaks to the user in the middle of normal workflow — a plan expired, a payment succeeded, a file upload failed. They sit inline with the content that caused them, stay on screen until dismissed or resolved, and carry one primary piece of information per box. Used well, an alert earns the user's attention exactly once.
Drivn's Alert ships four variants out of the box — default, info, success, and destructive — plus a title prop, an icon prop that accepts either a component reference (icon={Info}) or a pre-rendered element, and a children slot for the body copy. There is no AlertTitle or AlertDescription wrapper to import; the entire alert is one element you can read in a single glance.
This page collects five alert patterns you will actually ship: a default banner with a title, a variant showcase, a custom-icon alert, a dismissible alert backed by React state, and a data-driven version that renders a list from a server response. Every snippet is copy-paste and assumes you have installed Drivn via the CLI. For an engineering comparison against shadcn/ui's Alert, see Drivn vs shadcn/ui Alert.
Default alert with title
The canonical Drivn Alert is a single component with a title prop for the bold headline and children for the body copy. No wrapper elements, no sub-components, no AlertTitle or AlertDescription imports to remember. The default variant renders a neutral accent background with a subtle border — appropriate for informational banners that do not warrant the visual weight of info or success.
Drop this pattern at the top of a page, inside a card, or as a persistent banner in a dashboard header. The body text can hold an inline link, a code span, or any markup your copy needs — the alert docs show the full API reference.
1 import { Alert } from '@/components/ui/alert' 2 3 export default function Page() { 4 return ( 5 <Alert title="Heads up!"> 6 You can add components to your app using the CLI. 7 </Alert> 8 ) 9 }
All four variants
Drivn's Alert ships with default, info, success, and destructive variants. Each pairs a color-tuned border, background tint, and text color from the Drivn token system, so informational banners look blue, successes look green, and errors look red without any extra Tailwind configuration. For a project with one or two variants you will not notice the difference; for products that display mixed states across a dashboard, the extra two defaults save a round of variant definition per component.
Use info for non-critical context (a trial countdown), success for completed actions, and destructive for conditions the user must address. Save default for neutral-toned banners like an announcement bar. See the feedback category for how Alert pairs with Toast, Progress, and Tooltip across different surfaces.
1 import { Info, CheckCircle, XCircle } from 'lucide-react' 2 import { Alert } from '@/components/ui/alert' 3 4 <Alert variant="default" title="Heads up"> 5 Default alert for neutral announcements. 6 </Alert> 7 8 <Alert variant="info" icon={Info} title="Info"> 9 Your trial expires in 3 days. 10 </Alert> 11 12 <Alert variant="success" icon={CheckCircle} title="Success"> 13 Your changes have been saved. 14 </Alert> 15 16 <Alert variant="destructive" icon={XCircle} title="Error"> 17 Something went wrong. Please try again. 18 </Alert>
Custom icon
The icon prop accepts either a component reference (icon={Info}) or a pre-rendered React element (icon={<Info className="size-5 text-primary" />}). The component-reference form is concise and matches the pattern used by the Button (leftIcon={Plus}). Use it for the common case where the default icon size and color are fine.
The element form gives per-alert control — a larger icon on a hero banner, a custom color for a branded variant, or an inline SVG that is not in your Lucide set. Any component matching ComponentType<{ className?: string }> works, so you can pass a third-party icon set or a project-specific SVG component without adapters. See the theming guide for how to tint icons via token colors.
1 import { Info, Shield, Zap } from 'lucide-react' 2 import { Alert } from '@/components/ui/alert' 3 4 // component reference — concise 5 <Alert variant="info" icon={Info} title="Did you know?"> 6 You can customize alerts with any icon. 7 </Alert> 8 9 // pre-rendered element — full control 10 <Alert 11 variant="success" 12 icon={<Shield className="size-5 text-success" />} 13 title="Secure" 14 > 15 Connection is end-to-end encrypted. 16 </Alert> 17 18 // any custom component 19 <Alert icon={Zap} title="Fast"> 20 Response times under 100ms. 21 </Alert>
Dismissible alert
Drivn's Alert does not ship a built-in close button because most alert surfaces do not need one — inline errors resolve when the user fixes the underlying issue; status banners stay until the status changes. For the cases that do need dismissal (announcement bars, first-run tips, paid-feature upsells), wrap the Alert in a component that owns an open state and conditionally renders.
The snippet below adds a close button in the top-right corner using the Button with variant="ghost" and an X icon. Persist the dismissed state with localStorage if the alert should stay gone across page loads. For a stack of alerts that auto-dismiss on a timer, use the Toast component instead — toasts are built for transient notifications with a timeline.
1 'use client' 2 import * as React from 'react' 3 import { X, Info } from 'lucide-react' 4 import { Alert } from '@/components/ui/alert' 5 import { Button } from '@/components/ui/button' 6 7 export function DismissibleAlert() { 8 const [open, setOpen] = React.useState(true) 9 return ( 10 <div className="relative"> 11 {open && ( 12 <Alert variant="info" icon={Info} title="New feature"> 13 You can now schedule posts ahead of time. 14 </Alert> 15 )} 16 <Button 17 variant="ghost" 18 size="sm" 19 className="absolute top-2 right-2" 20 onClick={() => setOpen(false)} 21 aria-label="Dismiss" 22 > 23 <X className="size-4" /> 24 </Button> 25 </div> 26 ) 27 }
Render alerts from an array
Server-returned errors, CMS-driven announcements, and notification lists all arrive as arrays of objects. Map over the array and render one Alert per item. Use the object's stable id as the React key, the variant field as the alert's variant, and the message field as children. Pair with a filter to show only active alerts, or with a sort to put the most severe at the top of the list.
This pattern also works for per-field form errors — render one destructive Alert above the form for server-side failures that touch multiple fields at once. For field-level inline errors, use each input's error prop instead — see the React Hook Form guide for the full form-integration pattern.
1 import { Alert } from '@/components/ui/alert' 2 3 const alerts = [ 4 { 5 id: 1, 6 variant: 'info' as const, 7 title: 'Maintenance', 8 message: 'Scheduled downtime on Sunday at 2am UTC.', 9 }, 10 { 11 id: 2, 12 variant: 'success' as const, 13 title: 'Deployed', 14 message: 'v1.20 is live in production.', 15 }, 16 { 17 id: 3, 18 variant: 'destructive' as const, 19 title: 'Quota', 20 message: 'You are over your monthly API limit.', 21 }, 22 ] 23 24 <div className="flex flex-col gap-3"> 25 {alerts.map((a) => ( 26 <Alert key={a.id} variant={a.variant} title={a.title}> 27 {a.message} 28 </Alert> 29 ))} 30 </div>
Install Drivn in one command
Copy the source into your project and own every line. Zero runtime dependencies, pure React + Tailwind.
npx drivn@latest createRequires Node 18+. Works with npm, pnpm, and yarn.
Frequently asked questions
Wrap the Alert in a component that owns an open state with React.useState(true), and conditionally return null when dismissed. Add a close button positioned absolutely in the corner using the Button component with variant="ghost" and an X icon. For persistence across page loads, store the dismissed state in localStorage keyed by the alert's id and read it on mount.
Alerts are persistent and inline — they stay on the page until the underlying condition resolves or the user dismisses them, and they render in normal document flow next to the content that caused them. Toasts are transient and floating — they stack in a corner, auto-dismiss after a timer, and are better for confirming completed actions ("Saved", "Sent"). Use an alert for unresolved conditions, and a toast for completed-action confirmations.
Yes. The children prop is a standard React node, so you can render paragraphs, links, inline code spans, emphasized text, and even buttons inside the alert body. Keep the content to one primary message per alert — if you find yourself adding two actions or three paragraphs, you probably want a Dialog or a Drawer. Inline links inside the alert body work; just style them with a class that matches your link pattern.
Yes. The icon prop accepts any React component that matches the ComponentType<{ className?: string }> signature, which covers every icon in lucide-react. You can also pass a pre-rendered JSX element if you need to override the default size or color per alert, or a custom SVG component from your design system. Non-Lucide icon sets work as long as they accept a className prop.
Render the Alert conditionally based on whether the server returned an error message. Use the destructive variant, set the title to a short noun phrase ("Save failed"), and put the server's message or a friendly rewrite in the children. For field-level errors use each input's error prop instead. For a list of errors at the top of a form, map them over a single destructive Alert rendered above the form.
Drivn Alerts do not include entrance or exit animations by default. Add them in the parent component — a fadeIn keyframe on the container, a slideDown from above, or a tween via framer-motion if you already use it. Because the Alert source lives in your repo after install, you can also add animation classes directly to the styles.base string in src/components/ui/alert.tsx.