Avatar
A visual representation of a user that displays initials when an image is unavailable

PB
import {
Avatar,
AvatarFallback,
AvatarImage,
} from '@/components/avatar';
export default function AvatarPreview() {
return (
<Avatar>
<AvatarImage src="https://github.com/pdrbrnd.png" />
<AvatarFallback>Pedro Brandão</AvatarFallback>
</Avatar>
);
} Source Code
'use client';
import { UserIcon } from '@phosphor-icons/react';
import type { VariantProps } from 'cva';
import { cn, cva } from '@/lib/utils/classnames';
const getInitials = (name: string | undefined) => {
if (!name) return '';
if (name.length === 1 || name.length === 2) return name;
return name
.split(' ')
.map((n) => n[0])
.join('');
};
const avatarStyle = cva({
base: 'relative flex items-center justify-center overflow-hidden bg-foreground-secondary/10 font-semibold text-foreground/80 shadow-[inset_0_0_0_1px_--alpha(var(--color-foreground)/8%)] backdrop-blur-sm',
variants: {
variant: {
circle: 'rounded-full',
square: 'rounded-md',
},
size: {
'2xs': 'size-4 text-2xs',
xs: 'size-6 text-2xs',
sm: 'size-8 text-xs',
md: 'size-10 text-sm',
lg: 'size-12 text-base',
xl: 'size-14 text-lg',
'2xl': 'size-16 text-xl',
'3xl': 'size-20 text-3xl',
},
},
});
interface AvatarProps extends React.ComponentPropsWithRef<'div'> {
size?: VariantProps<typeof avatarStyle>['size'];
variant?: VariantProps<typeof avatarStyle>['variant'];
}
const Avatar = ({
className,
variant = 'circle',
size = 'md',
children,
...props
}: AvatarProps) => {
return (
<div className={cn(avatarStyle({ variant, size }), className)} {...props}>
{children}
</div>
);
};
interface AvatarImageProps extends React.ComponentPropsWithRef<'img'> {
src: string;
}
const AvatarImage = ({ className, src, ...props }: AvatarImageProps) => {
return (
<img
className={cn('absolute inset-0 z-1 object-cover', className)}
src={src}
alt=""
{...props}
/>
);
};
interface AvatarFallbackProps extends React.ComponentPropsWithRef<'div'> {
children?: string;
}
const AvatarFallback = ({
className,
children,
...props
}: AvatarFallbackProps) => {
return (
<div className={cn('opacity-80', className)} {...props}>
{getInitials(children) || <UserIcon weight="bold" />}
</div>
);
};
export { Avatar, AvatarFallback, AvatarImage }; Anatomy
<Avatar>
<AvatarImage />
<AvatarFallback />
</Avatar>
API Reference
Avatar
Extends the div element.
| Prop | Default | Type |
|---|---|---|
size | "md" | "2xs""xs""sm""md""lg""xl""2xl""3xl" |
variant | "circle" | "circle""square" |
AvatarImage
Extends the img element.
| Prop | Default | Type |
|---|---|---|
src | - | string |
AvatarFallback
Extends the div element.
| Prop | Default | Type |
|---|---|---|
children | - | string |
Examples
Simple

PB
import {
Avatar,
AvatarFallback,
AvatarImage,
} from '@/components/avatar';
export default function AvatarPreview() {
return (
<Avatar>
<AvatarImage src="https://github.com/pdrbrnd.png" />
<AvatarFallback>Pedro Brandão</AvatarFallback>
</Avatar>
);
} Fallback
PB
S
PB
import { Avatar, AvatarFallback } from '@/components/avatar';
export default function AvatarFallbackPreview() {
return (
<div className="flex flex-wrap gap-2">
{/* Full name */}
<Avatar>
<AvatarFallback>Pedro Brandão</AvatarFallback>
</Avatar>
{/* One word */}
<Avatar>
<AvatarFallback>Significa</AvatarFallback>
</Avatar>
{/* Initials */}
<Avatar>
<AvatarFallback>PB</AvatarFallback>
</Avatar>
{/* No fallback */}
<Avatar>
<AvatarFallback />
</Avatar>
</div>
);
} Sizes
PB
PB
PB
PB
PB
PB
PB
PB
import { Avatar, AvatarFallback } from '@/components/avatar';
export default function AvatarSizesPreview() {
return (
<div className="flex flex-wrap items-center gap-2">
<Avatar size="2xs">
<AvatarFallback>Pedro Brandão</AvatarFallback>
</Avatar>
<Avatar size="xs">
<AvatarFallback>Pedro Brandão</AvatarFallback>
</Avatar>
<Avatar size="sm">
<AvatarFallback>Pedro Brandão</AvatarFallback>
</Avatar>
<Avatar size="md">
<AvatarFallback>Pedro Brandão</AvatarFallback>
</Avatar>
<Avatar size="lg">
<AvatarFallback>Pedro Brandão</AvatarFallback>
</Avatar>
<Avatar size="xl">
<AvatarFallback>Pedro Brandão</AvatarFallback>
</Avatar>
<Avatar size="2xl">
<AvatarFallback>Pedro Brandão</AvatarFallback>
</Avatar>
<Avatar size="3xl">
<AvatarFallback>Pedro Brandão</AvatarFallback>
</Avatar>
</div>
);
} Broken Image
PB
import {
Avatar,
AvatarFallback,
AvatarImage,
} from '@/components/avatar';
export default function AvatarBrokenImagePreview() {
return (
<Avatar>
<AvatarImage src="broken-image-url" />
<AvatarFallback>Pedro Brandão</AvatarFallback>
</Avatar>
);
} On top of media
PB
import { Avatar, AvatarFallback } from '@/components/avatar';
export default function AvatarOnTopOfMediaPreview() {
return (
<div
className="relative size-32 overflow-hidden rounded-lg bg-center bg-cover"
style={{
backgroundImage:
'url(https://images.unsplash.com/photo-1682687220742-aba13b6e50ba?q=80)',
}}
>
<div className="flex h-full items-center justify-center">
<Avatar>
<AvatarFallback>Pedro Brandão</AvatarFallback>
</Avatar>
</div>
</div>
);
} Custom color
Previous
Setup
Next
Badge