Back to catalog
Component detail entry
Data Display
@vean/ui
SAvatar

Avatar

Avatar belongs to the Data Display category. Start with demos and usage, then use the API tables to finish integration and styling decisions.

Use the quick jump panel to reach overview, usage, demos, and API first, then continue through the full page.

Quick jump

Related components

If you are composing interactions in the same family, these components usually pair well together.

Avatar

Overview

An image element with a fallback for representing the user. SAvatar combines a AvatarRoot/AvatarImage/AvatarFallback family of Aria primitives (zero styles) with the avatarVariants style recipe (3 slots: root/image/fallback, 6 sizes xs–2xl).

Use it for user profiles, team/participant lists, or any spot that needs an identity image that degrades gracefully when the picture is slow, missing, or fails to load. Prefer image or icon for static or decorative imagery that has no identity fallback; prefer skeleton when you want to reserve space before content arrives.

SAvatar aggregates the primitives through AvatarCompact and exposes a src-driven API with fallback-label and delay-ms. For fully custom compositions, fall back to the Aria AvatarRoot/AvatarImage/AvatarFallback primitives.

Usage

Features

  • 🧩 Aria/styled split — AvatarCompact aggregates AvatarRoot/AvatarImage/AvatarFallback and exposes image/fallback slots; SAvatar only injects styles and forwards slots/events
  • 🖼️ Graceful loading — the image is shown only once it has actually loaded; while loading or on error the fallback text/slot is rendered instead
  • 🎭 Fallback slot — a custom fallback slot replaces the text label for initials, icons, or any VNode
  • ⏱️ Delay control — delay-ms defers the fallback so it only appears for slower connections
  • 🎨 6 sizes — xs–2xl sizing with size matching the shared ThemeSize scale
  • ♿ Accessible by default — the loaded image inherits the fallback label as its accessible name, and the default fallback text is rendered as real content; axe-core reports zero violations
  • 🧩 Fully customizable — per-slot ui overrides, root class override, and image/fallback slots replacing the defaults

Component family

  • SAvatar (styled) — the entry wrapper; avatarVariants recipe with dynamic slot forwarding
  • AvatarRoot (Aria) — the container; owns the shared image-loading state via provideAvatarRootContext
  • AvatarImage (Aria) — the <img>; tracked through useImageLoadingStatus and hidden until loaded
  • AvatarFallback (Aria) — the fallback content; rendered only when the image is not loaded (and after delay-ms)
  • AvatarCompact (Aria) — the aggregated composite; composes root/image/fallback and defaults the image alt to fallback-label

Demos

Basic

S

API

Aria Layer

5

Avatar

8 Props1 Emits
Props
PropTypeDefaultDescription
class
ClassValue
—
root class
size
ThemeSize
—
Visual size of the component.
ui
Partial<AvatarUi>
—
Per-slot class overrides for the component.
src
string
—
The image source URL.
delayMs
number
undefined
Useful for delaying fallback rendering so it only appears for those with slower connections.
fallbackLabel
string
—
Fallback text rendered when no custom fallback slot is provided.
imageProps
AvatarImageProps
—
Properties forwarded to the image element.
fallbackProps
AvatarFallbackProps
—
Properties forwarded to the fallback element.
Emits
Emit NameParametersDescription
loadingStatusChange
ImageLoadingStatus
Event handler called when the image loading status changes. This is useful for controlling what to render as the image is loading.

AvatarCompact

5 Props1 Emits3 Slots
Props
PropTypeDefaultDescription
src
string
—
The image source URL.
delayMs
number
undefined
Useful for delaying fallback rendering so it only appears for those with slower connections.
fallbackLabel
string
—
Fallback text rendered when no custom fallback slot is provided.
imageProps
AvatarImageProps
—
Properties forwarded to the image element.
fallbackProps
AvatarFallbackProps
—
Properties forwarded to the fallback element.
Emits
Emit NameParametersDescription
loadingStatusChange
ImageLoadingStatus
Event handler called when the image loading status changes. This is useful for controlling what to render as the image is loading.
Slots
Slot NameParametersDescription
default
—
Custom content for the default slot.
image
—
Custom content for the image slot.
fallback
—
Custom content for the fallback slot.

AvatarFallback

1 Props
Props
PropTypeDefaultDescription
delayMs
number
undefined
Useful for delaying rendering so it only appears for those with slower connections.

AvatarImage

4 Props1 Emits
Props
PropTypeDefaultDescription
src
string
—
The image source URL
alt
string
undefined
Alternate text for the image. When unset the avatar's fallback label is used so the loaded image keeps an accessible name; set to `''` to mark a purely decorative avatar.
referrerpolicy
('' | 'no-referrer' | 'no-referrer-when-downgrade' | 'origin' | 'origin-when-cross-origin' | 'same-origin' | 'strict-origin' | 'strict-origin-when-cross-origin' | 'unsafe-url')
—
The referrer policy for the image
crossorigin
'' | 'anonymous' | 'use-credentials'
—
The cross-origin setting for the image
Emits
Emit NameParametersDescription
loadingStatusChange
ImageLoadingStatus
Event handler called when the image loading status changes. This is useful for controlling what to render as the image is loading.

AvatarRoot

Notes

Architecture and benchmark differences

AvatarCompact owns the load-state orchestration (which part shows when) while every primitive stays style-free and only the UI wrapper injects the avatarVariants classes. This mirrors shadcn/ui’s Avatar/AvatarImage/AvatarFallback headless trio and Radix’s Avatar primitive, unlike Ant Design, Element Plus, Mantine and Naive UI which ship a single styled Avatar component with an alt/src prop. VeanUI deliberately routes the fallback text and image alt through the aggregate (fallback-label), so the loaded image keeps an accessible name without forcing consumers to repeat it.

CapabilityVeanUIshadcn/uiAnt Design AvatarElement Plus AvatarMantine AvatarNaive UI Avatar
Aria/styled split✅✅————
Image + fallback text/slot✅✅✅✅✅✅
Fallback delay (delay-ms)✅✅————
Accessible name auto-derived✅—————
Composite with per-part props✅✅————
Configurable size (ThemeSize)✅class✅✅✅✅

— = unsupported or a different interaction model (AntD/Element Plus/Mantine/Naive UI ship a single styled component; shadcn/ui leaves the image alt to the consumer and provides no fallback delay).

Cautions

  • The image is only rendered (and its alt exposed) after it loads; before that the fallback is the visible content. Do not rely on the image element existing in the DOM before the load event.
  • When the image fails, loadingStatusChange emits 'error' and the fallback stays visible. Listen to this event to drive logging or retries.
  • A fallback-label is used both as the fallback text and as the loaded image’s accessible name. Set imageProps.alt to '' if the avatar is purely decorative and should be skipped by assistive technology.
  • delay-ms only delays the fallback; the image still starts loading immediately, so a fast network still prefers the picture.
  • The root is a <span> (not a <button>/link), so it is not focusable or interactive by default — wrap it in a link/button when it should be clickable.

FAQ

How do I show initials when the image has not loaded yet?

Pass fallback-label (or the fallback slot) — it renders while the image is loading or after a failure:

<SAvatar src="https://example.com/avatar.png" fallback-label="JD" />

How do I delay the fallback for slow connections?

Use :delay-ms; the fallback only appears after the given milliseconds have elapsed without the image loading:

<SAvatar src="https://example.com/avatar.png" fallback-label="JD" :delay-ms="1000" />

How do I use an icon instead of text as the fallback?

Use the fallback slot to render any content:

<SAvatar src="https://example.com/avatar.png">
  <template #fallback><SIcon icon="lucide:user" /></template>
</SAvatar>

How do I react to a failed image load?

Listen to @loading-status-change; it emits 'loading' / 'loaded' / 'error':

<SAvatar src="https://example.com/avatar.png" fallback-label="JD" @loading-status-change="onStatus" />

How do I make a purely decorative avatar?

Set imageProps.alt to '' so assistive technology skips it:

<SAvatar src="https://example.com/logo.png" :image-props="{ alt: '' }" />

Changelog

Version history is grouped by release so you can quickly see what changed for this component across published versions.

v0.40.0

2026-09-14

Compare release

Docs

replace demo image with r2-hosted logo

Scope: avatarAuthors: soybeanfeView commit5b7d0

v0.18.0

2026-05-05

Compare release

Feature

add AvatarCompact component with props and emits

Scope: avatarAuthors: soybeanjsView commit7d59d

v0.0.7

2025-12-09

Compare release

Breaking

add image source and delay properties to AvatarProps for enhanced image handling

Scope: avatarAuthors: soybeanjsView commitf55e1

v0.0.2

2025-11-18

Compare release

Feature

introduce Avatar component with fallback and image loading features

Scope: avatarAuthors: soybeanjsView commit31a55

Feature

introduce SAvatar component with theme context support and refactor avatar structure for improved usability

Scope: avatarAuthors: soybeanjsView commit94542

Refactor

simplify loading status change function by removing console log

Scope: avatarAuthors: soybeanjsView commit325c4

Feature

introduce Avatar component with fallback and image loading features

Scope: avatarAuthors: soybeanjsView commit31a55

Feature

introduce SAvatar component with theme context support and refactor avatar structure for improved usability

Scope: avatarAuthors: soybeanjsView commit94542

Refactor

simplify loading status change function by removing console log

Scope: avatarAuthors: soybeanjsView commit325c4