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.
Overview
The Alert component in HeroUI v3 has been redesigned with a compound component pattern, requiring explicit structure with Alert.Title, Alert.Description, and Alert.Icon components.
Structure Changes
v2: Single Component with Props
In v2, Alert was a single component that accepted props for title, description, icon, and other elements:
import { Alert } from "@heroui/react";
<Alert
title="Alert Title"
description="Alert description"
color="success"
variant="flat"
/>v3: Compound Component Structure
In v3, Alert uses a compound component pattern with explicit subcomponents:
import { Alert } from "@heroui/react";
<Alert status="success">
<Alert.Indicator />
<Alert.Content>
<Alert.Title>Alert Title</Alert.Title>
<Alert.Description>Alert description</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 |
<Alert color="primary" title="Alert" /><Alert status="accent">
<Alert.Indicator />
<Alert.Content>
<Alert.Title>Alert</Alert.Title>
</Alert.Content>
</Alert>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. Removed Props
The following props are no longer available in v3:
variant- Use Tailwind CSS classes insteadradius- Use Tailwind CSS classes likerounded-lg,rounded-full, etc.startContent- Place content directly before<Alert.Indicator />endContent- Place content directly after<Alert.Content />hideIcon- Simply don't render<Alert.Indicator />hideIconWrapper- Not applicable (no wrapper in v3)isVisible/isDefaultVisible/onVisibleChange- Handle visibility manually with conditional renderingisClosable/onClose/closeButtonProps- Add a close button manually usingCloseButtoncomponent
5. Icon Handling
v2: Used icon prop or hideIcon prop
v3: Use <Alert.Indicator /> with custom children or omit it entirely
Migration Examples
Basic Usage
import { Alert } from "@heroui/react";
export default function App() {
return (
<Alert
title="This is an alert"
description="Thanks for subscribing to our newsletter!"
/>
);
}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>
);
}With Colors/Status
<Alert color="success" title="Success!" />
<Alert color="warning" title="Warning!" />
<Alert color="danger" title="Error!" /><Alert status="success">
<Alert.Indicator />
<Alert.Content>
<Alert.Title>Success!</Alert.Title>
</Alert.Content>
</Alert>
<Alert status="warning">
<Alert.Indicator />
<Alert.Content>
<Alert.Title>Warning!</Alert.Title>
</Alert.Content>
</Alert>
<Alert status="danger">
<Alert.Indicator />
<Alert.Content>
<Alert.Title>Error!</Alert.Title>
</Alert.Content>
</Alert>Custom Icon
import { Icon } from '@iconify/react';
<Alert
icon={<Icon icon="gravity-ui:box" />}
title="Custom Icon Alert"
/>import { Icon } from '@iconify/react';
<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
hideIcon
title="No Icon Alert"
/><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>
)}Controlled Visibility
import { Alert, Button } from "@heroui/react";
import { useState } from "react";
const [isVisible, setIsVisible] = useState(true);
<>
{isVisible ? (
<Alert
title="Success Notification"
isVisible={isVisible}
onVisibleChange={setIsVisible}
onClose={() => setIsVisible(false)}
/>
) : (
<Button onPress={() => setIsVisible(true)}>
Show Alert
</Button>
)}
</>import { Alert, Button, CloseButton } from "@heroui/react";
import { useState } from "react";
const [isVisible, setIsVisible] = useState(true);
<>
{isVisible ? (
<Alert status="success">
<Alert.Indicator />
<Alert.Content>
<Alert.Title>Success Notification</Alert.Title>
</Alert.Content>
<CloseButton
aria-label="Close"
onPress={() => setIsVisible(false)}
/>
</Alert>
) : (
<Button onPress={() => setIsVisible(true)}>
Show Alert
</Button>
)}
</>With Radius
<Alert
title="Rounded Alert"
radius="full"
/><Alert className="rounded-full">
<Alert.Indicator />
<Alert.Content>
<Alert.Title>Rounded Alert</Alert.Title>
</Alert.Content>
</Alert>With Variants (Using Tailwind Classes)
<Alert
title="Bordered Alert"
variant="bordered"
color="success"
/><Alert
status="success"
className="border-2 border-success"
>
<Alert.Indicator />
<Alert.Content>
<Alert.Title>Bordered Alert</Alert.Title>
</Alert.Content>
</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
│ ├── Alert.Title (optional)
│ └── Alert.Description (optional)
└── [Additional content like buttons, close button, etc.]Breaking Changes 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
Tips for Migration
- Start with structure: Convert the component structure first, then handle props
- Use conditional rendering: Replace
isVisibleprop with conditional rendering - Add close button manually: Import and use
CloseButtonfrom@heroui/react - Leverage Tailwind: Many removed props can be replaced with Tailwind utility classes
- Status mapping: Remember
primary→accentandsecondary→default
Need Help?
For v3 Alert features and API:
- See the API Reference
- Check interactive examples
For community support: