Avatar
Migration guide for Avatar from HeroUI v2 to v3
Refer to the v3 Avatar documentation for complete API reference, styling guide, and advanced examples. This guide only focuses on migrating from HeroUI v2.
Overview
The Avatar component in HeroUI v3 has been redesigned with a compound component pattern, requiring explicit structure with Avatar.Image and Avatar.Fallback components.
Structure Changes
v2: Single Component with Props
In v2, Avatar was a single component that accepted props for image source, name, fallback, and other elements:
import { Avatar } from "@heroui/react";
<Avatar
src="https://example.com/avatar.jpg"
name="John Doe"
showFallback
/>v3: Compound Component Structure
In v3, Avatar uses a compound component pattern with explicit subcomponents:
import { Avatar } from "@heroui/react";
<Avatar>
<Avatar.Image src="https://example.com/avatar.jpg" alt="John Doe" />
<Avatar.Fallback>JD</Avatar.Fallback>
</Avatar>Key Changes
1. Component Structure
v2: Single Avatar component with props
v3: Compound components: Avatar, Avatar.Image, Avatar.Fallback
2. Image and Fallback Handling
v2: Used src, name, showFallback, and fallback props
v3: Must explicitly render <Avatar.Image /> and <Avatar.Fallback /> components
3. Color Props
| v2 Color | v3 Color | Notes |
|---|---|---|
default | default | Same |
primary | accent | Renamed |
secondary | default | Use default color |
success | success | Same |
warning | warning | Same |
danger | danger | Same |
4. Removed Props
The following props are no longer available in v3:
name- Generate initials manually and pass to<Avatar.Fallback />showFallback- Fallback is always shown if image fails to loadicon- Place icon content directly in<Avatar.Fallback />isBordered- Use Tailwind CSS classes likering-2 ring-backgroundradius- Use Tailwind CSS classes likerounded-full,rounded-lg, etc.isDisabled- Use Tailwind CSS classes with opacityisFocusable- Not applicable (useasChildif needed)getInitials- Generate initials manuallyImgComponent/imgProps- UseasChildprop onAvatar.Imageif neededonError- UseonErrorprop onAvatar.ImageinsteadclassNames- UseclassNameprops on individual components
5. AvatarGroup Removed
v2: Had a dedicated AvatarGroup component
v3: No AvatarGroup component - create groups manually with CSS classes
Migration Examples
Basic Usage
import { Avatar } from "@heroui/react";
export default function App() {
return (
<Avatar
src="https://example.com/avatar.jpg"
name="John Doe"
showFallback
/>
);
}import { Avatar } from "@heroui/react";
export default function App() {
return (
<Avatar>
<Avatar.Image
src="https://example.com/avatar.jpg"
alt="John Doe"
/>
<Avatar.Fallback>JD</Avatar.Fallback>
</Avatar>
);
}Sizes
<Avatar size="sm" src="..." />
<Avatar size="md" src="..." />
<Avatar size="lg" src="..." /><Avatar size="sm">
<Avatar.Image src="..." alt="..." />
<Avatar.Fallback>S</Avatar.Fallback>
</Avatar>
<Avatar size="md">
<Avatar.Image src="..." alt="..." />
<Avatar.Fallback>M</Avatar.Fallback>
</Avatar>
<Avatar size="lg">
<Avatar.Image src="..." alt="..." />
<Avatar.Fallback>L</Avatar.Fallback>
</Avatar>Colors
<Avatar color="primary" name="John" />
<Avatar color="success" name="Jane" />
<Avatar color="danger" name="Joe" /><Avatar color="accent">
<Avatar.Fallback>J</Avatar.Fallback>
</Avatar>
<Avatar color="success">
<Avatar.Fallback>J</Avatar.Fallback>
</Avatar>
<Avatar color="danger">
<Avatar.Fallback>J</Avatar.Fallback>
</Avatar>Custom Fallback
import { Icon } from "@iconify/react";
<Avatar
src="https://broken-url.com/image.jpg"
showFallback
fallback={<Icon icon="mdi:account" />}
/>import { Icon } from "@iconify/react";
<Avatar>
<Avatar.Image
src="https://broken-url.com/image.jpg"
alt="User"
/>
<Avatar.Fallback>
<Icon icon="mdi:account" />
</Avatar.Fallback>
</Avatar>Bordered Avatar
<Avatar
isBordered
src="https://example.com/avatar.jpg"
/><Avatar className="ring-2 ring-background">
<Avatar.Image src="https://example.com/avatar.jpg" alt="User" />
<Avatar.Fallback>U</Avatar.Fallback>
</Avatar>Radius
<Avatar radius="full" src="..." />
<Avatar radius="lg" src="..." />
<Avatar radius="md" src="..." /><Avatar className="rounded-full">
<Avatar.Image src="..." alt="..." className="rounded-full" />
<Avatar.Fallback className="rounded-full">F</Avatar.Fallback>
</Avatar>
<Avatar className="rounded-lg">
<Avatar.Image src="..." alt="..." className="rounded-lg" />
<Avatar.Fallback className="rounded-lg">L</Avatar.Fallback>
</Avatar>
<Avatar className="rounded-md">
<Avatar.Image src="..." alt="..." className="rounded-md" />
<Avatar.Fallback className="rounded-md">M</Avatar.Fallback>
</Avatar>Avatar Group
import { Avatar, AvatarGroup } from "@heroui/react";
<AvatarGroup isBordered>
<Avatar src="https://example.com/1.jpg" />
<Avatar src="https://example.com/2.jpg" />
<Avatar src="https://example.com/3.jpg" />
</AvatarGroup>import { Avatar } from "@heroui/react";
<div className="flex -space-x-2">
<Avatar className="ring-2 ring-background">
<Avatar.Image src="https://example.com/1.jpg" alt="User 1" />
<Avatar.Fallback>U1</Avatar.Fallback>
</Avatar>
<Avatar className="ring-2 ring-background">
<Avatar.Image src="https://example.com/2.jpg" alt="User 2" />
<Avatar.Fallback>U2</Avatar.Fallback>
</Avatar>
<Avatar className="ring-2 ring-background">
<Avatar.Image src="https://example.com/3.jpg" alt="User 3" />
<Avatar.Fallback>U3</Avatar.Fallback>
</Avatar>
</div>Avatar Group with Max Count
import { Avatar, AvatarGroup } from "@heroui/react";
<AvatarGroup max={3}>
<Avatar src="https://example.com/1.jpg" />
<Avatar src="https://example.com/2.jpg" />
<Avatar src="https://example.com/3.jpg" />
<Avatar src="https://example.com/4.jpg" />
<Avatar src="https://example.com/5.jpg" />
</AvatarGroup>import { Avatar } from "@heroui/react";
const users = [
{ id: 1, src: "https://example.com/1.jpg", name: "User 1" },
{ id: 2, src: "https://example.com/2.jpg", name: "User 2" },
{ id: 3, src: "https://example.com/3.jpg", name: "User 3" },
{ id: 4, src: "https://example.com/4.jpg", name: "User 4" },
{ id: 5, src: "https://example.com/5.jpg", name: "User 5" },
];
<div className="flex -space-x-2">
{users.slice(0, 3).map((user) => (
<Avatar key={user.id} className="ring-2 ring-background">
<Avatar.Image src={user.src} alt={user.name} />
<Avatar.Fallback>
{user.name.split(" ").map(n => n[0]).join("")}
</Avatar.Fallback>
</Avatar>
))}
<Avatar className="ring-2 ring-background">
<Avatar.Fallback className="border-none">
+{users.length - 3}
</Avatar.Fallback>
</Avatar>
</div>Disabled Avatar
<Avatar
isDisabled
src="https://example.com/avatar.jpg"
/><Avatar className="opacity-50 cursor-not-allowed">
<Avatar.Image src="https://example.com/avatar.jpg" alt="User" />
<Avatar.Fallback>U</Avatar.Fallback>
</Avatar>Variants
{/* v2 doesn't have variants, but uses color prop */}
<Avatar color="primary" name="John" />{/* v3 has variant prop */}
<Avatar variant="soft" color="accent">
<Avatar.Fallback>J</Avatar.Fallback>
</Avatar>Styling Changes
v2: classNames Prop
<Avatar
classNames={{
base: "custom-base",
img: "custom-img",
fallback: "custom-fallback"
}}
/>v3: Direct className Props
<Avatar className="custom-base">
<Avatar.Image className="custom-img" src="..." alt="..." />
<Avatar.Fallback className="custom-fallback">
JD
</Avatar.Fallback>
</Avatar>Component Anatomy
The v3 Avatar follows this structure:
Avatar (Root)
├── Avatar.Image (optional)
└── Avatar.Fallback (always shown if image fails or not provided)Helper Function for Initials
Since v3 doesn't have a name prop, you'll need to generate initials manually:
function getInitials(name: string): string {
return name
.split(" ")
.map(n => n[0])
.join("")
.toUpperCase()
.slice(0, 2);
}
// Usage
<Avatar>
<Avatar.Fallback>{getInitials("John Doe")}</Avatar.Fallback>
</Avatar>Breaking Changes Summary
- Component Structure: Must use compound components (
Avatar.Image,Avatar.Fallback) - Name Prop Removed: Generate initials manually
- ShowFallback Removed: Fallback always shows if image fails
- Color Mapping:
primary→accent,secondary→default - Bordered Removed: Use Tailwind
ring-2 ring-backgroundclasses - Radius Removed: Use Tailwind
rounded-*classes - Disabled Removed: Use Tailwind
opacity-50classes - AvatarGroup Removed: Create groups manually with CSS
- Icon Prop Removed: Place icon content in
Avatar.Fallback - ClassNames Removed: Use
classNameprops on individual components
Tips for Migration
- Start with structure: Convert to compound components first
- Generate initials: Create a helper function for name-to-initials conversion
- Handle fallbacks: Always include
<Avatar.Fallback />for better UX - Use Tailwind: Many removed props can be replaced with Tailwind utility classes
- Avatar groups: Use
-space-x-2andring-2 ring-backgroundfor overlapping avatars - Image alt text: Always provide
altprop onAvatar.Imagefor accessibility
Need Help?
For v3 Avatar features and API:
- See the API Reference
- Check interactive examples
For community support: