Avatar
A component for displaying user avatars with an image and fallback content.
Avatar is the React Native implementation shipped by the native-avatar registry item. The component adapts the registry's web-facing composition to native primitives and touch-based interaction.
The native Avatar component provides a consistent circular container for profile images. It is composed of Avatar, AvatarImage, and AvatarFallback, allowing the fallback content to appear while an image is loading or when the image fails to load.
The component manages image state internally. When an image successfully loads, the fallback is hidden. When the image cannot be loaded, the fallback remains visible.
See the shadcn/ui Avatar documentation for the web component API, concepts, and additional examples.
Installation
CLI
npx shadcn add https://ui.tiesen.id.vn/r/native-avatar.jsonManual
Copy and paste the following code into your project.
import * as React from 'react'import { Image, View } from 'react-native'import { cn } from '@/lib/utils'import { Typography } from '@/components/native/typography'interface AvatarContextValue { isLoaded: boolean hasError: boolean setIsLoaded: (loaded: boolean) => void setHasError: (error: boolean) => void}const AvatarContext = React.createContext<AvatarContextValue | null>(null)function Avatar({ className, children, ...props}: React.ComponentProps<typeof View>) { const [isLoaded, setIsLoaded] = React.useState(false) const [hasError, setHasError] = React.useState(false) const memoizedValue = React.useMemo( () => ({ isLoaded, hasError, setIsLoaded, setHasError }), [isLoaded, hasError] ) return ( <AvatarContext value={memoizedValue}> <View data-slot='avatar' accessibilityRole='image' className={cn( 'relative flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-full border border-border bg-muted', className )} {...props} > {children} </View> </AvatarContext> )}function AvatarImage({ className, source, onLoad, onError, ...props}: React.ComponentProps<typeof Image>) { const ctx = React.use(AvatarContext) if (!ctx) throw new Error('AvatarImage must be used within an Avatar component') const { hasError, setIsLoaded, setHasError } = ctx if (!source || hasError) return null return ( <Image data-slot='avatar-image' source={source} onLoad={(e) => { setIsLoaded(true) onLoad?.(e) }} onError={(e) => { setHasError(true) onError?.(e) }} className={cn('size-full rounded-full', className)} {...props} /> )}function AvatarFallback({ className, children, ...props}: React.ComponentProps<typeof View>) { const ctx = React.use(AvatarContext) if (!ctx) throw new Error('AvatarFallback must be used within an Avatar component') const { isLoaded, hasError } = ctx if (isLoaded && !hasError) return null return ( <View data-slot='avatar-fallback' className={cn( 'absolute inset-0 flex size-full items-center justify-center rounded-full bg-muted', className )} {...props} > {typeof children === 'string' ? ( <Typography className='text-xs font-medium text-muted-foreground'> {children} </Typography> ) : ( children )} </View> )}export { Avatar, AvatarImage, AvatarFallback }Features
- Image loading state is tracked automatically.
- Fallback content is shown before the image loads and after an image error.
- Images are clipped to the avatar shape.
- Uses the native React Native
ImageandViewprimitives. - Provides an image accessibility role on the root avatar.
Registry dependencies: This component also installs
native-typographythrough the registry dependency graph.
Usage
import {
Avatar,
AvatarFallback,
AvatarImage,
} from '@/components/native/avatar'
export function AvatarExample() {
return (
<Avatar>
<AvatarImage
source={{ uri: 'https://i.pravatar.cc/160?img=12' }}
/>
<AvatarFallback>JD</AvatarFallback>
</Avatar>
)
}Fallback content
AvatarFallback is rendered until the image reports a successful load. This makes it safe to use the same composition for both remote and local images.
<Avatar>
<AvatarImage source={{ uri: profile.avatarUrl }} />
<AvatarFallback>JD</AvatarFallback>
</Avatar>If source is missing or the image reports an error, AvatarImage renders nothing and the fallback remains visible.
Custom sizes and styles
The native avatar defaults to a size-10 circular container. Because the components accept native View/Image props and className, you can change the dimensions or appearance.
<Avatar className='size-12'>
<AvatarImage source={require('@/assets/avatar.png')} />
<AvatarFallback>TS</AvatarFallback>
</Avatar>API Reference
Avatar
The root avatar container.
| Prop | Type | Default |
|---|---|---|
className | string | — |
children | React.ReactNode | — |
...props | React.ComponentProps<typeof View> | — |
AvatarImage
Renders the image and reports loading/error state to the parent Avatar.
| Prop | Type | Default |
|---|---|---|
source | ImageSourcePropType | — |
onLoad | ImageProps['onLoad'] | — |
onError | ImageProps['onError'] | — |
className | string | — |
...props | React.ComponentProps<typeof Image> | — |
AvatarImage must be rendered inside Avatar.
AvatarFallback
Fallback content shown while the image is unavailable.
| Prop | Type | Default |
|---|---|---|
children | React.ReactNode | — |
className | string | — |
...props | React.ComponentProps<typeof View> | — |
AvatarFallback must be rendered inside Avatar.