Components / Media

Avatar

Avatar shows a person's profile image, and falls back to their initials when the image is absent or fails to load. One required prop — name — drives both states, so they always describe the same person.

Loading playground…
Updated 3 days agoEdit on GitHubWeb & native

What it is

A fixed-size, circular (or rounded-square) container. When src is set and the image loads, Avatar renders it. When src is absent — or the load fails — Avatar renders initials computed from name, or the explicit fallback node if you supply one.

The name prop is required for a reason: it is the image's alt text and the source of the initials. A consumer cannot end up with an image that has no description, or a fallback that names someone different from the photo.

Install

Avatar is exported from usemotif. No separate install.

example.tsx
import { Avatar } from 'usemotif';

API

Avatar

stable
function Avatar(props: AvatarProps): JSX.Element
namestringrequired

The person's name. Used as the image `alt` text and as the source of the initials fallback.

srcstring

Image URL. When absent or the load fails, Avatar shows the fallback instead.

fallbackReactNode

Overrides the generated initials. Use for a placeholder glyph or a custom node.

size"xs" | "sm" | "md" | "lg" | "xl" | number= "md"

Size token (24 / 32 / 40 / 56 / 80px) or a raw pixel number.

shape"circle" | "square"= "circle"

Circle or rounded square.

Accessibility

Avatar guarantees a description in both states. With an image, name becomes the alt. Without one, the initials are visible text — but initials alone are a poor description, so when the fallback shows, name is still the accessible name of the element. A screen-reader user hears "Jane Doe", not "JD", regardless of which state rendered.

The name prop being required is the mechanism. There is no code path that produces an undescribed Avatar.

Examples

With an image:

example.tsx
<Avatar name="Jane Doe" src={user.avatarUrl} size="lg" />

Initials fallback — no src:

example.tsx
<Avatar name="Anil Kapoor" />

A row of avatars:

example.tsx
<HStack gap="$1">
{team.map((member) => (
  <Avatar key={member.id} name={member.name} src={member.avatarUrl} size="sm" />
))}
</HStack>