> ## Documentation Index
> Fetch the complete documentation index at: https://docs.twenty.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Avatar

> Represent a person or record with an image, initial, or icon.

export const StoryEmbed = ({storyId, title, height = 120}) => <>
    <Tabs>
      <Tab title="Light">
        <iframe title={`${title} (light)`} src={`https://storybook.twenty.com/iframe.html?id=${storyId}&viewMode=story&globals=colorScheme:light`} width="100%" height={height} loading="lazy" allow="clipboard-write" style={{
  border: 0
}} />
      </Tab>
      <Tab title="Dark">
        <iframe title={`${title} (dark)`} src={`https://storybook.twenty.com/iframe.html?id=${storyId}&viewMode=story&globals=colorScheme:dark`} width="100%" height={height} loading="lazy" allow="clipboard-write" style={{
  border: 0
}} />
      </Tab>
    </Tabs>
    <a href={`https://storybook.twenty.com/?path=/story/${storyId}`}>
      Open in Storybook
    </a>
  </>;

`Avatar` shows an image with a first-letter fallback. Use it beside a record name or inside a [Chip](/ui/primitives/data-display/chip). Its default root is a presentational `span`.

<StoryEmbed storyId="ui-data-display-avatar--display" title="Avatar example" height={90} />

## Usage

```tsx theme={null}
import { Avatar } from 'twenty-ui/primitives/data-display';

export const WorkspaceAvatar = () => (
  <Avatar
    name="Acme"
    colorSeed="acme-app"
    shape="square"
    variant="outline"
    size="md"
  />
);
```

When the image is absent or fails to load, the fallback shows the first letter of the trimmed name in uppercase. An empty name shows `-`. `colorSeed` chooses stable fallback colors and defaults to `name`; use a record identifier to keep the color stable when the name changes.

The image and default fallback are decorative. `name` supplies the visual initial and fallback colors without adding an accessible label. When the avatar is the only representation of a person or record, set `imageProps={{ alt: name }}` to label both the image and default fallback. Keep the avatar decorative when a visible name or labeled owner already provides that information.

`imageProps` accepts the complete image contract, including `srcSet`, `sizes`, `crossOrigin`, `referrerPolicy`, native events, refs, and `render`. Its `src` overrides the shorthand `src`. `fallbackProps` accepts the complete fallback contract, including `delay`, children, labeling, refs, and `render`. A custom fallback `render` owns its accessibility semantics; set `aria-hidden` explicitly when it is decorative.

```tsx theme={null}
import { Avatar } from 'twenty-ui/primitives/data-display';

type RecordAvatarProps = {
  name: string;
  imageUrl?: string;
  initials: string;
};

export const RecordAvatar = ({
  name,
  imageUrl,
  initials,
}: RecordAvatarProps) => (
  <Avatar
    name={name}
    src={imageUrl}
    size="lg"
    imageProps={{ alt: name, decoding: 'async', referrerPolicy: 'no-referrer' }}
    fallbackProps={{ children: initials, delay: 150 }}
  />
);
```

## Compose the parts

Use `Avatar.Root`, `Avatar.Image`, and `Avatar.Fallback` when you own the anatomy. Root supplies the size, shape, and fallback appearance; it does not generate children or accessible labels.

```tsx theme={null}
import { Avatar } from 'twenty-ui/primitives/data-display';

type ContactAvatarProps = {
  name: string;
  imageUrl?: string;
  initials: string;
};

export const ContactAvatar = ({
  name,
  imageUrl,
  initials,
}: ContactAvatarProps) => (
  <Avatar.Root name={name} shape="circle" size="xl">
    <Avatar.Image src={imageUrl} alt={name} decoding="async" />
    <Avatar.Fallback role="img" aria-label={name} delay={150}>
      {initials}
    </Avatar.Fallback>
  </Avatar.Root>
);
```

<StoryEmbed storyId="ui-data-display-avatar--parts" title="Avatar parts" height={110} />

The parts share Base UI's image loading state. Image renders an `img` after a successful load by default, and Fallback renders a `span` while the image is absent, loading, or has failed. `delay` postpones the initial fallback display in milliseconds and defaults to `0`. A changed source is loaded again and can replace either the current image or fallback.

`Avatar.Image` exposes `onLoadingStatusChange` with `idle`, `loading`, `loaded`, and `error` status values. The callback runs when Base UI reports a non-idle status change; unmounting the Image part resets the shared root state to `idle`. Root, Image, and Fallback accept state-aware `className`, `style`, and `render` functions with `imageLoadingStatus`; Image also exposes `transitionStatus`.

Use `keepMounted` on Image when the rendered image must load in place, including `loading="lazy"` or an optimized image component. Forward native attributes, events, and the ref from custom image renderers. A mounted image can still be loading or failed; inspect loading state rather than treating its presence as success.

The front component renderer currently supports the default preload path with `src`. Its host image does not receive `srcSet`, `sizes`, `loading`, `decoding`, or `referrerPolicy`. A changing custom `render` function with `keepMounted` can leave a decoded image hidden because the worker cannot read its completion state or dimensions. Use default preloading there until those renderer capabilities are available.

The public `AvatarRootProps`, `AvatarImageProps`, `AvatarFallbackProps`, `AvatarRootState`, `AvatarImageState`, `AvatarFallbackState`, and `AvatarImageLoadingStatus` types are exported from `twenty-ui/primitives/data-display`. Refs target the rendered DOM element: `span`, `img`, and `span` by default, or the element supplied through `render`.

## Shape and appearance

<StoryEmbed storyId="ui-data-display-avatar--catalog" title="Avatar sizes and shapes" height={320} />

`shape` accepts `square`, `rounded-square`, or `circle`. Sizes run from `xs` (12px) to `xl` (40px); `md` is 16px. `variant="outline"` adds a border to the fallback. The `color`, `backgroundColor`, and `borderColor` overrides customize the fallback, while a loaded image keeps its original appearance.

```tsx theme={null}
import { IconUser } from 'twenty-ui/icon';
import { Avatar } from 'twenty-ui/primitives/data-display';

export const ContactIcon = () => (
  <Avatar
    icon={<IconUser />}
    shape="rounded-square"
    size="xl"
    role="img"
    aria-label="Contact"
  />
);
```

An `icon` takes precedence over both the image and the first-letter fallback. The icon itself is decorative, so label the root when it conveys information. `pulsing` animates opacity and respects reduced-motion preferences.

## Open a profile

```tsx theme={null}
import { Avatar } from 'twenty-ui/primitives/data-display';

type ProfileAvatarProps = {
  onOpenProfile: () => void;
  disabled?: boolean;
};

export const ProfileAvatar = ({
  onOpenProfile,
  disabled = false,
}: ProfileAvatarProps) => (
  <Avatar
    name="Jane"
    shape="circle"
    size="lg"
    render={
      <button
        type="button"
        disabled={disabled}
        aria-label="Open Jane's profile"
        onClick={onOpenProfile}
      />
    }
  />
);
```

<StoryEmbed storyId="ui-data-display-avatar--button-composition" title="Avatar composed as a button" height={110} />

Compose a native button for actions. It owns focus, Enter and Space activation, and disabled behavior. Supply an action-specific accessible name. Put `onClick` and `disabled` on the rendered button; shorthand Avatar has no `onClick`, `disabled`, or `nativeButton` prop.

For navigation, compose an anchor with an `href` or a router link that preserves anchor semantics. Native links activate with Enter. Keep navigation and disabled behavior with the link or interactive component you compose.

```tsx theme={null}
import { Avatar } from 'twenty-ui/primitives/data-display';

export const ProfileLink = () => (
  <Avatar
    name="Jane"
    shape="circle"
    size="lg"
    render={<a href="/people/jane" aria-label="Open Jane's profile" />}
  />
);
```

## Migrate clickable avatars

Compose a native button through `render` for actions, or an anchor or router link for navigation. Move `onClick` and `disabled` onto that owner and remove `nativeButton`. Give the owner a useful accessible name and avoid nesting interactive elements. `Avatar.Root` and the other explicit parts retain the complete Base UI event contract.

Shorthand avatars are decorative by default. `name` does not name the image, fallback, or interactive owner. Use a nonempty `imageProps.alt` only when the avatar conveys identity that is not already supplied by visible text or an owner label. With explicit parts, supply image alternative text and fallback labels or decorative attributes yourself, and keep translated content in your application.

## Props

Types and defaults are generated from the public component types. The explicit parts accept native attributes and event handlers. Shorthand Avatar omits `onClick`; supply it on the owner passed through `render`.

<ParamField body="backgroundColor" type="string">
  Background color override for a first-letter fallback.
</ParamField>

<ParamField body="borderColor" type="string">
  Border color override for the outline fallback.
</ParamField>

<ParamField body="className" type="string | ((state: AvatarRootState) => string | undefined)">
  CSS class applied to the element, or a function that
  returns a class based on the component's state.
</ParamField>

<ParamField body="color" type="string">
  Text color override for a first-letter fallback.
</ParamField>

<ParamField body="colorSeed" type="string">
  Stable value used to choose fallback colors. Defaults to `name`.
</ParamField>

<ParamField body="fallbackProps" type="AvatarFallbackProps">
  Complete `Avatar.Fallback` props, including caller-owned children, labeling, refs, `render`, and fallback `delay` in milliseconds.
</ParamField>

<ParamField body="icon" type="ReactNode">
  Decorative icon rendered instead of the image and first-letter fallback. Give the root an accessible label when the icon conveys information.
</ParamField>

<ParamField body="imageProps" type="AvatarImageProps">
  Complete `Avatar.Image` props, including native image attributes, refs, `render`, `keepMounted`, and `onLoadingStatusChange`. Alternative text defaults to an empty string. Supply a nonempty `alt` to label the image and default fallback.
</ParamField>

<ParamField body="name" type="string">
  Name used for the first-letter fallback and fallback colors. Does not add an accessible label.
</ParamField>

<ParamField body="pulsing" type="boolean" default="false">
  Animates the avatar opacity. Respects reduced-motion preferences.
</ParamField>

<ParamField body="render" type="ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, AvatarRootState>">
  Caller-supplied root element or renderer. Defaults to a presentational span. Compose a native button or link explicitly for interaction, and put its click handler and disabled state on that owner.
</ParamField>

<ParamField body="ring" type="boolean" default="false">
  Surrounds the avatar with a background-colored ring so overlapping avatars stay distinct.
</ParamField>

<ParamField body="shape" type="&#x22;circle&#x22; | &#x22;rounded-square&#x22; | &#x22;square&#x22;" default="square">
  Shape of the avatar and its fallback.
</ParamField>

<ParamField body="size" type="&#x22;lg&#x22; | &#x22;md&#x22; | &#x22;sm&#x22; | &#x22;xl&#x22; | &#x22;xs&#x22;" default="md">
  Avatar size: `xs` (12px), `sm` (14px), `md` (16px), `lg` (24px), or `xl` (40px).
</ParamField>

<ParamField body="src" type="string | null">
  Image URL. A missing or failed image shows the fallback. `imageProps.src` overrides this value.
</ParamField>

<ParamField body="style" type="CSSProperties | ((state: AvatarRootState) => CSSProperties | undefined)">
  Style applied to the element, or a function that
  returns a style object based on the component's state.
</ParamField>

<ParamField body="variant" type="&#x22;outline&#x22; | &#x22;soft&#x22;" default="soft">
  Visual treatment of the fallback.
</ParamField>

### Avatar.Root

<ParamField body="Root.backgroundColor" type="string">
  Background color override for a first-letter fallback.
</ParamField>

<ParamField body="Root.borderColor" type="string">
  Border color override for the outline fallback.
</ParamField>

<ParamField body="Root.children" type="ReactNode">
  Caller-owned Image, Fallback, and other content.
</ParamField>

<ParamField body="Root.className" type="string | ((state: AvatarRootState) => string | undefined)">
  CSS class applied to the element, or a function that
  returns a class based on the component's state.
</ParamField>

<ParamField body="Root.color" type="string">
  Text color override for a first-letter fallback.
</ParamField>

<ParamField body="Root.colorSeed" type="string">
  Stable value used to choose fallback colors. Defaults to `name`.
</ParamField>

<ParamField body="Root.name" type="string">
  Name used to choose fallback colors. Does not add children or accessible labels.
</ParamField>

<ParamField body="Root.pulsing" type="boolean" default="false">
  Animates the avatar opacity. Respects reduced-motion preferences.
</ParamField>

<ParamField body="Root.render" type="ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, AvatarRootState>">
  Caller-supplied root element or renderer. Defaults to a presentational span. Compose a native button or link explicitly for interaction, and put its click handler and disabled state on that owner.
</ParamField>

<ParamField body="Root.ring" type="boolean" default="false">
  Surrounds the avatar with a background-colored ring so overlapping avatars stay distinct.
</ParamField>

<ParamField body="Root.shape" type="&#x22;circle&#x22; | &#x22;rounded-square&#x22; | &#x22;square&#x22;" default="square">
  Shape of the avatar and its fallback.
</ParamField>

<ParamField body="Root.size" type="&#x22;lg&#x22; | &#x22;md&#x22; | &#x22;sm&#x22; | &#x22;xl&#x22; | &#x22;xs&#x22;" default="md">
  Avatar size: `xs` (12px), `sm` (14px), `md` (16px), `lg` (24px), or `xl` (40px).
</ParamField>

<ParamField body="Root.style" type="CSSProperties | ((state: AvatarRootState) => CSSProperties | undefined)">
  Style applied to the element, or a function that
  returns a style object based on the component's state.
</ParamField>

<ParamField body="Root.variant" type="&#x22;outline&#x22; | &#x22;soft&#x22;" default="soft">
  Visual treatment of the fallback.
</ParamField>

### Avatar.Image

<ParamField body="Image.alt" type="string">
  Caller-owned alternative text. Use an empty string for decorative images.
</ParamField>

<ParamField body="Image.className" type="string | ((state: AvatarImageState) => string | undefined)">
  CSS class applied to the element, or a function that
  returns a class based on the component's state.
</ParamField>

<ParamField body="Image.crossOrigin" type="&#x22;&#x22; | &#x22;anonymous&#x22; | &#x22;use-credentials&#x22;">
  Native image cross-origin policy, also used during preloading.
</ParamField>

<ParamField body="Image.keepMounted" type="boolean" default="false">
  Keeps the image mounted and loads it in place. Loading and failed images stay hidden while Fallback is shown.
</ParamField>

<ParamField body="Image.loading" type="&#x22;eager&#x22; | &#x22;lazy&#x22;">
  Native eager or lazy loading. Use keepMounted for lazy loading.
</ParamField>

<ParamField body="Image.onLoadingStatusChange" type="((status: ImageLoadingStatus) => void)">
  Called when Base UI reports a loading, loaded, or error status. Shares that state with Root and Fallback.
</ParamField>

<ParamField body="Image.referrerPolicy" type="&#x22;&#x22; | &#x22;no-referrer-when-downgrade&#x22; | &#x22;no-referrer&#x22; | &#x22;origin-when-cross-origin&#x22; | &#x22;origin&#x22; | &#x22;same-origin&#x22; | &#x22;strict-origin-when-cross-origin&#x22; | &#x22;strict-origin&#x22; | &#x22;unsafe-url&#x22;">
  Native image referrer policy, also used during preloading.
</ParamField>

<ParamField body="Image.render" type="ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<DetailedHTMLProps<ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, AvatarImageState>">
  Replaces the image. Preserve a native image and forward the supplied attributes, events, and ref.
</ParamField>

<ParamField body="Image.sizes" type="string">
  Native responsive image sizes used with srcSet.
</ParamField>

<ParamField body="Image.src" type="string">
  Image URL. Image renders after a successful load unless keepMounted is enabled.
</ParamField>

<ParamField body="Image.srcSet" type="string">
  Native responsive image source candidates.
</ParamField>

<ParamField body="Image.style" type="CSSProperties | ((state: AvatarImageState) => CSSProperties | undefined)">
  Style applied to the element, or a function that
  returns a style object based on the component's state.
</ParamField>

### Avatar.Fallback

<ParamField body="Fallback.children" type="ReactNode">
  Caller-owned fallback content, such as initials or an icon.
</ParamField>

<ParamField body="Fallback.className" type="string | ((state: AvatarFallbackState) => string | undefined)">
  CSS class applied to the element, or a function that
  returns a class based on the component's state.
</ParamField>

<ParamField body="Fallback.delay" type="number" default="0">
  Milliseconds before the initial fallback is shown. Defaults to 0.
</ParamField>

<ParamField body="Fallback.render" type="ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, AvatarFallbackState>">
  Replaces the fallback span. Forward the supplied props and ref, and provide its accessible label or decorative attributes.
</ParamField>

<ParamField body="Fallback.style" type="CSSProperties | ((state: AvatarFallbackState) => CSSProperties | undefined)">
  Style applied to the element, or a function that
  returns a style object based on the component's state.
</ParamField>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.