Avatar
Display user or entity profile images with a fallback when the image is missing or still loading.
Import
vue
<script setup lang="ts">
import { Avatar, AvatarFallback, AvatarImage } from '@heroui-vue/vue'
</script>Usage
Basic
<template>
<div class="demo-avatar-row">
<Avatar>
<AvatarImage
alt="John Doe"
src="https://img.heroui.chat/image/avatar?w=400&h=400&u=3"
/>
<AvatarFallback>JD</AvatarFallback>
</Avatar>
<Avatar>
<AvatarImage
alt="Blue"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/blue.jpg"
/>
<AvatarFallback>B</AvatarFallback>
</Avatar>
<Avatar>
<AvatarFallback>JR</AvatarFallback>
</Avatar>
</div>
</template>
<script setup lang="ts">
import { Avatar, AvatarFallback, AvatarImage } from '@heroui-vue/vue'
</script>
<style lang="less">
.demo-avatar-row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 1rem;
}
</style>Anatomy
vue
<template>
<Avatar>
<AvatarImage src="..." alt="..." />
<AvatarFallback>JD</AvatarFallback>
</Avatar>
</template>Sizes
<template>
<div class="demo-avatar-row">
<Avatar size="sm">
<AvatarImage
alt="Small Avatar"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/blue.jpg"
/>
<AvatarFallback>SM</AvatarFallback>
</Avatar>
<Avatar size="md">
<AvatarImage
alt="Medium Avatar"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/purple.jpg"
/>
<AvatarFallback>MD</AvatarFallback>
</Avatar>
<Avatar size="lg">
<AvatarImage
alt="Large Avatar"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/red.jpg"
/>
<AvatarFallback>LG</AvatarFallback>
</Avatar>
</div>
</template>
<script setup lang="ts">
import { Avatar, AvatarFallback, AvatarImage } from '@heroui-vue/vue'
</script>
<style lang="less">
.demo-avatar-row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 1rem;
}
</style>Colors
DFACSCWRDG
<template>
<div class="demo-avatar-row">
<Avatar
v-for="item in colors"
:key="item.color"
:color="item.color"
>
<AvatarFallback>{{ item.label }}</AvatarFallback>
</Avatar>
</div>
</template>
<script setup lang="ts">
import { Avatar, AvatarFallback } from '@heroui-vue/vue'
const colors = [
{ color: 'default', label: 'DF' },
{ color: 'accent', label: 'AC' },
{ color: 'success', label: 'SC' },
{ color: 'warning', label: 'WR' },
{ color: 'danger', label: 'DG' },
] as const
</script>
<style lang="less">
.demo-avatar-row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 1rem;
}
</style>Variants
accent
default
success
warning
danger
letter
AG
DG
SG
WG
DG
letter soft
AG
DG
SG
WG
DG
icon
icon soft
img
<template>
<div class="demo-avatar-variants">
<div class="demo-avatar-variant-row">
<div class="demo-avatar-variant-label" />
<div
v-for="color in colors"
:key="color"
class="demo-avatar-variant-cell"
>
<span class="demo-avatar-variant-header">{{ color }}</span>
</div>
</div>
<Separator />
<div
v-for="row in rows"
:key="row.label"
class="demo-avatar-variant-row"
>
<div class="demo-avatar-variant-label">
{{ row.label }}
</div>
<div
v-for="(color, colorIndex) in colors"
:key="color"
class="demo-avatar-variant-cell"
>
<Avatar
:color="color"
:variant="row.soft ? 'soft' : undefined"
>
<AvatarImage
v-if="row.type === 'img'"
:alt="`Avatar ${color}`"
:src="images[colorIndex]"
/>
<AvatarFallback>
<PersonIcon v-if="row.type === 'icon'" />
<template v-else>
{{ color.slice(0, 1).toUpperCase() }}{{ row.type === 'img' ? '' : 'G' }}
</template>
</AvatarFallback>
</Avatar>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { defineComponent, h } from 'vue'
import { Avatar, AvatarFallback, AvatarImage, Separator } from '@heroui-vue/vue'
const colors = ['accent', 'default', 'success', 'warning', 'danger'] as const
const images = [
'https://img.heroui.chat/image/avatar?w=400&h=400&u=3',
'https://img.heroui.chat/image/avatar?w=400&h=400&u=4',
'https://img.heroui.chat/image/avatar?w=400&h=400&u=5',
'https://img.heroui.chat/image/avatar?w=400&h=400&u=8',
'https://img.heroui.chat/image/avatar?w=400&h=400&u=16',
]
const rows = [
{ label: 'letter', type: 'letter', soft: false },
{ label: 'letter soft', type: 'letter', soft: true },
{ label: 'icon', type: 'icon', soft: false },
{ label: 'icon soft', type: 'icon', soft: true },
{ label: 'img', type: 'img', soft: false },
] as const
const PersonIcon = defineComponent({
setup() {
return () =>
h(
'svg',
{
viewBox: '0 0 24 24',
fill: 'none',
stroke: 'currentColor',
'stroke-width': '2',
'stroke-linecap': 'round',
'stroke-linejoin': 'round',
'aria-hidden': 'true',
},
[
h('path', { d: 'M20 21a8 8 0 0 0-16 0' }),
h('path', { d: 'M12 13a5 5 0 1 0 0-10 5 5 0 0 0 0 10Z' }),
],
)
},
})
</script>
<style lang="less">
.demo-avatar-variants {
display: flex;
max-width: 100%;
flex-direction: column;
gap: 1rem;
overflow-x: auto;
text-align: left;
}
.demo-avatar-variant-row {
display: flex;
align-items: center;
gap: 0.75rem;
}
.demo-avatar-variant-label {
width: 6rem;
flex-shrink: 0;
color: var(--color-muted-foreground);
font-size: 0.875rem;
}
.demo-avatar-variant-cell {
display: flex;
width: 5rem;
flex-shrink: 0;
justify-content: center;
}
.demo-avatar-variant-header {
color: var(--color-muted-foreground);
font-size: 0.75rem;
text-transform: capitalize;
}
.avatar svg {
width: 1rem;
height: 1rem;
}
</style>Fallback Content
JD
GB
GB <template>
<div class="demo-avatar-row">
<Avatar>
<AvatarFallback>JD</AvatarFallback>
</Avatar>
<Avatar>
<AvatarFallback>
<PersonIcon />
</AvatarFallback>
</Avatar>
<Avatar>
<AvatarImage
alt="Delayed Avatar"
src="https://invalid-url-to-show-fallback.com/image.jpg"
/>
<AvatarFallback :delay-ms="600">
NA
</AvatarFallback>
</Avatar>
<Avatar>
<AvatarFallback class="demo-avatar-gradient-fallback">
GB
</AvatarFallback>
</Avatar>
</div>
</template>
<script setup lang="ts">
import { defineComponent, h } from 'vue'
import { Avatar, AvatarFallback, AvatarImage } from '@heroui-vue/vue'
const PersonIcon = defineComponent({
setup() {
return () =>
h(
'svg',
{
viewBox: '0 0 24 24',
fill: 'none',
stroke: 'currentColor',
'stroke-width': '2',
'stroke-linecap': 'round',
'stroke-linejoin': 'round',
'aria-hidden': 'true',
},
[
h('path', { d: 'M20 21a8 8 0 0 0-16 0' }),
h('path', { d: 'M12 13a5 5 0 1 0 0-10 5 5 0 0 0 0 10Z' }),
],
)
},
})
</script>
<style lang="less">
.demo-avatar-row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 1rem;
}
.avatar svg {
width: 1rem;
height: 1rem;
}
.demo-avatar-gradient-fallback {
background: linear-gradient(135deg, rgb(236 72 153), rgb(168 85 247));
color: white;
}
</style>Avatar Group
<template>
<div class="demo-avatar-stack">
<div class="demo-avatar-group">
<Avatar
v-for="user in users.slice(0, 4)"
:key="user.id"
class="demo-avatar-ring"
>
<AvatarImage
:alt="user.name"
:src="user.image"
/>
<AvatarFallback>{{ initials(user.name) }}</AvatarFallback>
</Avatar>
</div>
<div class="demo-avatar-group">
<Avatar
v-for="user in users.slice(0, 3)"
:key="user.id"
class="demo-avatar-ring"
>
<AvatarImage
:alt="user.name"
:src="user.image"
/>
<AvatarFallback>{{ initials(user.name) }}</AvatarFallback>
</Avatar>
<Avatar class="demo-avatar-ring">
<AvatarFallback class="demo-avatar-counter">
+{{ users.length - 3 }}
</AvatarFallback>
</Avatar>
</div>
</div>
</template>
<script setup lang="ts">
import { Avatar, AvatarFallback, AvatarImage } from '@heroui-vue/vue'
const users = [
{
id: 1,
image: 'https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/blue.jpg',
name: 'John Doe',
},
{
id: 2,
image: 'https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/green.jpg',
name: 'Kate Wilson',
},
{
id: 3,
image: 'https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/purple.jpg',
name: 'Emily Chen',
},
{
id: 4,
image: 'https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/orange.jpg',
name: 'Michael Brown',
},
{
id: 5,
image: 'https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/red.jpg',
name: 'Olivia Davis',
},
]
const initials = (name: string) =>
name
.split(' ')
.map((part) => part[0])
.join('')
</script>
<style lang="less">
.demo-avatar-stack {
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.demo-avatar-group {
display: flex;
}
.demo-avatar-group > .avatar + .avatar {
margin-left: -0.5rem;
}
.demo-avatar-ring {
box-shadow: 0 0 0 2px var(--vp-c-bg);
}
.demo-avatar-counter {
font-size: 0.75rem;
}
</style>Custom Styles
<template>
<div class="demo-avatar-row">
<Avatar class="demo-avatar-xl">
<AvatarImage
alt="Extra Large"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/blue.jpg"
/>
<AvatarFallback>XL</AvatarFallback>
</Avatar>
<Avatar class="demo-avatar-square">
<AvatarImage
alt="Square Avatar"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/purple.jpg"
/>
<AvatarFallback class="demo-avatar-square">
SQ
</AvatarFallback>
</Avatar>
<Avatar class="demo-avatar-gradient-border">
<div class="demo-avatar-gradient-inner">
<AvatarImage
alt="Gradient Border"
class="demo-avatar-rounded-image"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/red.jpg"
/>
<AvatarFallback>GB</AvatarFallback>
</div>
</Avatar>
<div class="demo-avatar-status-wrap">
<Avatar>
<AvatarImage
alt="Online User"
src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/orange.jpg"
/>
<AvatarFallback>ON</AvatarFallback>
</Avatar>
<span class="demo-avatar-status" />
</div>
</div>
</template>
<script setup lang="ts">
import { Avatar, AvatarFallback, AvatarImage } from '@heroui-vue/vue'
</script>
<style lang="less">
.demo-avatar-row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 1rem;
}
.demo-avatar-xl {
width: 4rem;
height: 4rem;
}
.demo-avatar-square {
border-radius: 0.5rem;
}
.demo-avatar-gradient-border {
padding: 0.125rem;
background: linear-gradient(45deg, rgb(236 72 153), rgb(234 179 8));
}
.demo-avatar-gradient-inner {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
border-radius: 999px;
background: var(--vp-c-bg);
}
.demo-avatar-rounded-image {
border-radius: 999px;
}
.demo-avatar-status-wrap {
position: relative;
}
.demo-avatar-status {
position: absolute;
right: 0;
bottom: 0;
width: 0.75rem;
height: 0.75rem;
border-radius: 999px;
background: rgb(34 197 94);
box-shadow: 0 0 0 2px var(--vp-c-bg);
}
</style>Styling
Passing Classes
vue
<template>
<Avatar class="size-20">
<AvatarImage src="..." alt="..." />
<AvatarFallback>XL</AvatarFallback>
</Avatar>
</template>CSS Classes
| Class | Description |
|---|---|
.avatar | Base avatar container |
.avatar__image | Image element |
.avatar__fallback | Fallback content container |
.avatar--sm | Small size |
.avatar--md | Medium size |
.avatar--lg | Large size |
.avatar--soft | Soft visual variant |
.avatar__fallback--default | Default fallback color |
.avatar__fallback--accent | Accent fallback color |
.avatar__fallback--success | Success fallback color |
.avatar__fallback--warning | Warning fallback color |
.avatar__fallback--danger | Danger fallback color |
API
Avatar Props
| Prop | Type | Default | Description |
|---|---|---|---|
size | 'sm' | 'md' | 'lg' | 'md' | Avatar size |
color | 'default' | 'accent' | 'success' | 'warning' | 'danger' | 'default' | Fallback color theme |
variant | 'default' | 'soft' | 'default' | Visual style variant |
class | string | undefined | Additional classes for the avatar root |
AvatarImage Props
| Prop | Type | Default | Description |
|---|---|---|---|
src | string | undefined | Image source URL |
srcset | string | undefined | Responsive image srcset |
sizes | string | undefined | Responsive image sizes |
alt | string | undefined | Alternative text |
crossorigin | 'anonymous' | 'use-credentials' | undefined | CORS setting |
loading | 'eager' | 'lazy' | undefined | Native image loading strategy |
class | string | undefined | Additional classes for the image |
AvatarImage Events
| Event | Payload | Description |
|---|---|---|
load | Event | Emitted when the image loads |
error | Event | Emitted when the image fails and fallback should show |
AvatarFallback Props
| Prop | Type | Default | Description |
|---|---|---|---|
delayMs | number | undefined | Delay before rendering fallback content |
color | 'default' | 'accent' | 'success' | 'warning' | 'danger' | Parent color | Override fallback color |
class | string | undefined | Additional classes for the fallback |
Slots
| Component | Slot | Description |
|---|---|---|
Avatar | default | Image and fallback content |
AvatarFallback | default | Text, icon, or custom fallback content |