Back to Heroui

Alert

apps/docs/content/docs/en/react/migration/(components)/alert.mdx

3.2.06.6 KB
Original Source
<Callout type="info"> Refer to the [v3 Alert documentation](/docs/react/components/alert) for complete API reference, styling guide, and advanced examples. This guide only focuses on migrating from HeroUI v2. </Callout>

Structure Changes

In v2, Alert was a single component that accepted props for title, description, icon, and other elements:

tsx
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:

tsx
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 Colorv3 StatusNotes
defaultdefaultSame
primaryaccentRenamed
secondarydefaultUse default status
successsuccessSame
warningwarningSame
dangerdangerSame

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 → v3 status + add background color classes
  • v2 bordered → v3 status + add border classes
  • v2 flat → v3 default (no additional classes needed)
  • v2 faded → v3 status + add opacity/background classes

4. Prop Changes

v2 Propv3 LocationNotes
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)
iconAlert.IndicatorRender icon as child of <Alert.Indicator />
isVisible, isDefaultVisible, onVisibleChange-Removed (handle with conditional rendering)
isClosable, onClose, closeButtonProps-Removed (add CloseButton manually)
titleAlert.TitleUse <Alert.Title> inside <Alert.Content>
descriptionAlert.DescriptionUse <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

<Tabs items={["v2", "v3"]}> <Tab value="v2"> tsx import { Icon } from '@iconify/react'; <Alert icon={<Icon icon="gravity-ui:box" />} title="Custom Icon Alert" /> <Alert hideIcon title="No Icon Alert" /> </Tab> <Tab value="v3"> tsx 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> <Alert> <Alert.Content> <Alert.Title>No Icon Alert</Alert.Title> </Alert.Content> </Alert> </Tab> </Tabs>

With Action Button (End Content)

<Tabs items={["v2", "v3"]}> <Tab value="v2"> ```tsx 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>
  }
/>
```
</Tab> <Tab value="v3"> ```tsx 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>
```
</Tab> </Tabs>

Closable Alert

<Tabs items={["v2", "v3"]}> <Tab value="v2"> tsx <Alert title="Closable Alert" isClosable onClose={() => console.log("Closed")} /> </Tab> <Tab value="v3"> ```tsx 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>
)}
```
</Tab> </Tabs>

Styling Changes

v2: classNames Prop

tsx
<Alert 
  classNames={{
    base: "custom-base",
    title: "custom-title",
    description: "custom-description"
  }}
/>

v3: Direct className Props

tsx
<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

  1. Component Structure: Must use compound components instead of props
  2. Color → Status: color prop renamed to status, primaryaccent, secondarydefault
  3. Variants Removed: No variant prop; use Tailwind CSS classes
  4. Radius Removed: No radius prop; use Tailwind CSS classes
  5. No Built-in Close Button: Must add CloseButton manually
  6. No Visibility Control: Handle visibility with conditional rendering
  7. No Start/End Content Props: Place content directly in the component tree
  8. Icon Handling: Use <Alert.Indicator /> with children or omit it