Skip to main content
Vuetify0 is now in beta!
Vuetify0 Logo
Theme
Mode
Palettes
Accessibility
Vuetify One
Sign in to Vuetify One

Access premium tools across the Vuetify ecosystem — Bin, Play, Studio, and more.

Not a subscriber? See what's included

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.

JD
FB

Anatomy

vue
<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.

Image/Fallback Flow

Use controls to zoom and pan. Click outside or press Escape to close.

Image/Fallback Flow
Tip

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 propPurpose
statusCurrent state: 'idle' | 'loading' | 'loaded' | 'error'
isLoadedTrue when the image has loaded successfully
isErrorTrue when the image failed to load
retryReset 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:

vue
<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.

FileRole
members.tsMember type + sample data; the kind of array your API would return
team.vuePanel UI — labelled Avatar.Group with hover tooltips on every avatar and the +N chip
Frontend Platform30 members
AL
GH
AT
LT
ED
SW
BK
CW
JD
KB
AB
MH
PN
FA
RP
OD
YM
TB
XP
CD
DK
HL
VC
NW
EH
IM
SK
MW
GR
WH
Was this page helpful?

Ctrl+/