apps/docs/content/docs/en/react/migration/(components)/avatar.mdx
In v2, Avatar was a single component that accepted props for image source, name, fallback, and other elements:
import { Avatar } from "@heroui/react";
export default function App() {
return (
<Avatar
src="https://example.com/avatar.jpg"
name="John Doe"
showFallback
/>
);
}
In v3, Avatar uses a compound component pattern with explicit subcomponents:
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>
);
}
v2: Single Avatar component with props
v3: Compound components: Avatar, Avatar.Image, Avatar.Fallback
| v2 Prop | v3 Location | Notes |
|---|---|---|
src | Avatar.Image | Use <Avatar.Image src="..." /> |
name | - | Generate initials and pass to <Avatar.Fallback /> |
showFallback | - | Removed (fallback shown if image fails or not provided) |
fallback, icon | Avatar.Fallback | Place content in <Avatar.Fallback /> |
color | Avatar | Same; primary → accent, secondary → default |
variant | Avatar | New in v3; "default" | "soft" |
size | Avatar | Same |
isBordered | - | Removed (use Tailwind e.g. ring-2 ring-background) |
radius | - | Removed (use Tailwind e.g. rounded-full) |
isDisabled, isFocusable | - | Removed (use Tailwind / asChild if needed) |
getInitials | - | Generate initials manually |
ImgComponent, imgProps | - | Use asChild on Avatar.Image if needed |
onError | Avatar.Image | Use onError on <Avatar.Image /> |
| - | Avatar.Image | New: srcSet, sizes, loading for responsive images |
| - | Avatar.Fallback | New: delayMs to delay fallback display (prevents flash) |
classNames | - | Use className on parts |
| AvatarGroup | - | No v3 equivalent; create groups with CSS |
v2: No variant prop; styling controlled only through color
v3: New variant prop with "default" and "soft" options. The "soft" variant applies a lighter background style.
<Avatar variant="soft" color="accent">
<Avatar.Image src="..." alt="User" />
<Avatar.Fallback>JD</Avatar.Fallback>
</Avatar>
v2: Limited to src and onError
v3: Avatar.Image now supports srcSet, sizes, and loading for responsive image handling
<Avatar>
<Avatar.Image
src="avatar-400.jpg"
srcSet="avatar-200.jpg 200w, avatar-400.jpg 400w"
sizes="(max-width: 600px) 200px, 400px"
loading="lazy"
alt="User"
/>
<Avatar.Fallback>JD</Avatar.Fallback>
</Avatar>
delayMs Prop (New in v3)v2: Fallback shown immediately or controlled via showFallback
v3: Avatar.Fallback supports a delayMs prop to delay rendering, preventing flash of fallback content when images load quickly
<Avatar>
<Avatar.Image src="..." alt="User" />
<Avatar.Fallback delayMs={600}>JD</Avatar.Fallback>
</Avatar>
v2: Used src, name, showFallback, and fallback props
v3: Must explicitly render <Avatar.Image /> and <Avatar.Fallback /> components
| 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 |
v2: Had a dedicated AvatarGroup component
v3: No AvatarGroup component - create groups manually with CSS classes
<Tabs items={["v2", "v3"]}>
<Tab value="v2">
tsx <Avatar size="md" color="primary" src="..." name="John" />
</Tab>
<Tab value="v3">
tsx <Avatar size="md" color="accent"> <Avatar.Image src="..." alt="John" /> <Avatar.Fallback>J</Avatar.Fallback> </Avatar>
</Tab>
</Tabs>
<Tabs items={["v2", "v3"]}> <Tab value="v2"> ```tsx import { Icon } from "@iconify/react";
<Avatar
src="https://broken-url.com/image.jpg"
showFallback
fallback={<Icon icon="mdi:account" />}
/>
```
<Avatar>
<Avatar.Image
src="https://broken-url.com/image.jpg"
alt="User"
/>
<Avatar.Fallback>
<Icon icon="mdi:account" />
</Avatar.Fallback>
</Avatar>
```
<Tabs items={["v2", "v3"]}> <Tab value="v2"> ```tsx 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>
```
<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>
```
<Tabs items={["v2", "v3"]}> <Tab value="v2"> ```tsx 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>
```
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>
```
<Tabs items={["v2", "v3"]}>
<Tab value="v2">
tsx <Avatar color="primary" name="John" />
</Tab>
<Tab value="v3">
tsx <Avatar variant="soft" color="accent"> <Avatar.Fallback>J</Avatar.Fallback> </Avatar>
</Tab>
</Tabs>
classNames Prop<Avatar
classNames={{
base: "custom-base",
img: "custom-img",
fallback: "custom-fallback"
}}
/>
className Props<Avatar className="custom-base">
<Avatar.Image className="custom-img" src="..." alt="..." />
<Avatar.Fallback className="custom-fallback">
JD
</Avatar.Fallback>
</Avatar>
The v3 Avatar follows this structure:
Avatar (Root)
├── Avatar.Image (optional)
└── Avatar.Fallback (optional; shown when image fails or not provided)
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>
Avatar.Image, Avatar.Fallback)variant prop ("default" | "soft") for visual style controlAvatar.Image now supports srcSet, sizes, and loading attributesAvatar.Fallback supports delayMs to prevent flash of fallback contentprimary → accent, secondary → defaultring-2 ring-background classesrounded-* classesopacity-50 classesAvatar.FallbackclassName props on individual components