Avatar
Headless image component with automatic fallback to icon or text content.
Usage
The Avatar component provides a robust image loading system with automatic fallback handling. It manages multiple image sources with priority ordering and only displays the highest-priority loaded image or fallback content.
Image and Fallback
Two avatars showing successful image loading and graceful fallback to initials when the image fails.
Anatomy
<script setup lang="ts">
import { Avatar } from '@vuetify/v0'
</script>
<template>
<Avatar.Root>
<Avatar.Image />
<Avatar.Fallback />
</Avatar.Root>
<Avatar.Group>
<Avatar.Root>
<Avatar.Image />
<Avatar.Fallback />
</Avatar.Root>
<Avatar.Indicator />
</Avatar.Group>
</template>Architecture
The Avatar uses an internal selection system with mandatory: 'force' to ensure exactly one element is always visible. Images register as disabled until they load successfully.
For single-source content images with placeholder and error fallback, use Image instead. Avatar specializes in identity / profile UIs with priority-based multi-source fallback.
Loading state slot props
Avatar.Image exposes the underlying loading state from useImage via slot props. Use these for custom transitions, retry UI, or status indicators.
| Slot prop | Purpose |
|---|---|
status | Current state: 'idle' | 'loading' | 'loaded' | 'error' |
isLoaded | True when the image has loaded successfully |
isError | True when the image failed to load |
retry | Reset the image and re-attempt loading |
Priority System
When multiple images are present, the priority prop determines display order. Higher priority images are preferred when loaded:
<template>
<Avatar.Root>
<!-- Preferred when loaded -->
<Avatar.Image src="/high-res.jpg" :priority="1" />
<!-- Fallback image -->
<Avatar.Image src="/low-res.jpg" :priority="0" />
<!-- Text fallback -->
<Avatar.Fallback>JD</Avatar.Fallback>
</Avatar.Root>
</template>Examples
Team roster
A realistic project-members panel — the kind of header you’d find on a Slack channel, GitHub team page, or Jira project view. The row fills the available chrome width and collapses into a +N chip when there isn’t enough room. The chip’s title lists everyone who’s currently hidden, so the truncation never costs the reader information.
The data lives in a separate module so the component stays focused on composition and ARIA. Each member is registered with :value="member" rather than just an id, which makes Avatar.Indicator’s hidden slot prop directly useful — the tooltip resolves names without a separate lookup. The negative marginInlineStart is skipped on the first child via the (member, index) form so the leading avatar doesn’t hang off the container’s left edge.
responsive opts the group into createOverflow under a useToggleScope, so groups that don’t need width tracking pay nothing. The indicator self-measures its width and writes it back via reserved on createOverflow, so the group always carves out exactly enough room for the chip — no hard-coded pixel reserve needed. Drag the example pane’s resize handle to watch the visible count adjust.
| File | Role |
|---|---|
members.ts | Member type + sample data; the kind of array your API would return |
team.vue | Panel UI — labelled Avatar.Group with hover tooltips on every avatar and the +N chip |
