Avatar Atom

Server-safe, and deliberately so: the initials render underneath and the image covers them once it loads, so a broken URL degrades to initials with no JavaScript and no flash of an empty circle.

Usage

+3
tsx
<Avatar name="Rio Hakim" size="lg" status="online" />
<AvatarGroup overflow={3}>  {members.map((member) => <Avatar key={member.id} name={member.name} src={member.photo} />)}</AvatarGroup>

The details that matter

  • Initials are first and last word, capped at two letters. Three stop fitting at sm, and a clipped initial reads as a rendering bug.
  • The fallback colour is derived from the name, so the same person keeps the same colour across sessions, devices, and anyone else's screen.
  • The image is alt="" — the accessible name lives on the wrapper, so a screen reader says the person's name once rather than twice.

Do

Pass the person's name even when you have a photo; it is the accessible name and the fallback both.

Don't

Use status dots for anything but presence — a green dot means 'here', and repurposing it confuses every reader.

Props

PropTypeDefaultNotes
namestringRequired. Accessible name, initials, and fallback hue.
srcstringPhoto. Covers the initials when it loads.
size'sm' | 'md' | 'lg' | 'xl''md'Token sizes.
hueDecorHueOverrides the name-derived colour.
status'online' | 'busy' | 'away' | 'offline'Presence dot.
AvatarGroup overflownumberRenders a "+N" chip after the stack.