Alert
Migration guide for Alert from HeroUI v2 to v3
Refer to the v3 Alert documentation for complete API reference, styling guide, and advanced examples. This guide only focuses on migrating from HeroUI v2.
Structure Changes
In v2, Alert was a single component that accepted props for title, description, icon, and other elements:
import { Alert } from "@heroui/react";
export default function App() {
return (
<Alert
title="This is an alert"
description="Thanks for subscribing to our newsletter!"
/>
);
}In v3, Alert uses a compound component pattern with explicit subcomponents:
import { Alert } from "@heroui/react";
export default function App() {
return (
<Alert>
<Alert.Indicator />
<Alert.Content>
<Alert.Title>This is an alert</Alert.Title>
<Alert.Description>
Thanks for subscribing to our newsletter!
</Alert.Description>
</Alert.Content>
</Alert>
);
}Key Changes
1. Component Structure
v2: Single Alert component with props
v3: Compound components: Alert, Alert.Indicator, Alert.Content, Alert.Title, Alert.Description
2. Color/Status Props
| v2 Color | v3 Status | Notes |
|---|---|---|
default | default | Same |
primary | accent | Renamed |
secondary | default | Use default status |
success | success | Same |
warning | warning | Same |
danger | danger | Same |
3. Variants Removed
v2 Variants: solid, bordered, flat, faded
v3: No variant prop - use Tailwind CSS classes to achieve similar effects
To achieve v2 variant styles in v3:
- v2
solid→ v3status+ add background color classes - v2
bordered→ v3status+ addborderclasses - v2
flat→ v3 default (no additional classes needed) - v2
faded→ v3status+ add opacity/background classes
4. Prop Changes
| v2 Prop | v3 Location | Notes |
|---|---|---|
variant | - | Removed (use Tailwind CSS) |
radius | - | Removed (use Tailwind e.g. rounded-lg) |
startContent | - | Place content before <Alert.Indicator /> |
endContent | - | Place content after <Alert.Content /> |
hideIcon | - | Omit <Alert.Indicator /> |
hideIconWrapper | - | Removed (no wrapper in v3) |
icon | Alert.Indicator | Render icon as child of <Alert.Indicator /> |
isVisible, isDefaultVisible, onVisibleChange | - | Removed (handle with conditional rendering) |
isClosable, onClose, closeButtonProps | - | Removed (add CloseButton manually) |
title | Alert.Title | Use <Alert.Title> inside <Alert.Content> |
description | Alert.Description | Use <Alert.Description> inside <Alert.Content> |
5. Icon Handling
v2: Used icon prop or hideIcon prop
v3: Use <Alert.Indicator /> with custom children or omit it entirely
Migration Examples
Icon Handling
import { Icon } from '@iconify/react';
{/* With custom icon */}
<Alert
icon={<Icon icon="gravity-ui:box" />}
title="Custom Icon Alert"
/>
{/* Without icon */}
<Alert hideIcon title="No Icon Alert" />import { Icon } from '@iconify/react';
{/* With custom icon */}
<Alert>
<Alert.Indicator>
<Icon icon="gravity-ui:box" />
</Alert.Indicator>
<Alert.Content>
<Alert.Title>Custom Icon Alert</Alert.Title>
</Alert.Content>
</Alert>
{/* Without icon */}
<Alert>
<Alert.Content>
<Alert.Title>No Icon Alert</Alert.Title>
</Alert.Content>
</Alert>With Action Button (End Content)
import { Alert, Button } from "@heroui/react";
<Alert
title="You have no credits left"
description="Upgrade to a paid plan to continue"
endContent={
<Button color="warning" size="sm" variant="flat">
Upgrade
</Button>
}
/>import { Alert, Button } from "@heroui/react";
<Alert status="warning">
<Alert.Indicator />
<Alert.Content>
<Alert.Title>You have no credits left</Alert.Title>
<Alert.Description>
Upgrade to a paid plan to continue
</Alert.Description>
<Button className="mt-2" size="sm" variant="primary">
Upgrade
</Button>
</Alert.Content>
</Alert>Closable Alert
<Alert
title="Closable Alert"
isClosable
onClose={() => console.log("Closed")}
/>import { Alert, CloseButton } from "@heroui/react";
import { useState } from "react";
const [isVisible, setIsVisible] = useState(true);
{isVisible && (
<Alert>
<Alert.Indicator />
<Alert.Content>
<Alert.Title>Closable Alert</Alert.Title>
</Alert.Content>
<CloseButton
aria-label="Close"
onPress={() => setIsVisible(false)}
/>
</Alert>
)}Styling Changes
v2: classNames Prop
<Alert
classNames={{
base: "custom-base",
title: "custom-title",
description: "custom-description"
}}
/>v3: Direct className Props
<Alert className="custom-base">
<Alert.Indicator />
<Alert.Content>
<Alert.Title className="custom-title">Title</Alert.Title>
<Alert.Description className="custom-description">
Description
</Alert.Description>
</Alert.Content>
</Alert>Component Anatomy
The v3 Alert follows this structure:
Alert (Root)
├── Alert.Indicator (optional)
├── Alert.Content (optional)
│ ├── Alert.Title (optional)
│ └── Alert.Description (optional)
└── [Additional content like buttons, close button, etc.] (optional)Summary
- Component Structure: Must use compound components instead of props
- Color → Status:
colorprop renamed tostatus,primary→accent,secondary→default - Variants Removed: No
variantprop; use Tailwind CSS classes - Radius Removed: No
radiusprop; use Tailwind CSS classes - No Built-in Close Button: Must add
CloseButtonmanually - No Visibility Control: Handle visibility with conditional rendering
- No Start/End Content Props: Place content directly in the component tree
- Icon Handling: Use
<Alert.Indicator />with children or omit it