27.5k

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 Colorv3 StatusNotes
defaultdefaultSame
primaryaccentRenamed
secondarydefaultUse default status
successsuccessSame
warningwarningSame
dangerdangerSame
<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 → 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. Removed Props

The following props are no longer available in v3:

  • variant - Use Tailwind CSS classes instead
  • radius - Use Tailwind CSS classes like rounded-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 rendering
  • isClosable / onClose / closeButtonProps - Add a close button manually using CloseButton component

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

  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

Tips for Migration

  1. Start with structure: Convert the component structure first, then handle props
  2. Use conditional rendering: Replace isVisible prop with conditional rendering
  3. Add close button manually: Import and use CloseButton from @heroui/react
  4. Leverage Tailwind: Many removed props can be replaced with Tailwind utility classes
  5. Status mapping: Remember primaryaccent and secondarydefault

Need Help?

For v3 Alert features and API:

For community support: