code/tamagui.dev/data/docs/components/image/2.0.0.mdx
<Highlights features={[ 'Supports SSR.', 'Works on native and web.', 'Accepts Tamagui style props.', 'Pluggable architecture with createImage for expo-image and more.', ]} />
Image is already installed in tamagui, or you can install it independently:
npm install @tamagui/image
Use the src prop for the image URL:
import { Image } from 'tamagui'
export default () => (
<Image src="https://example.com/photo.jpg" width={200} height={200} />
)
You can also use objectFit to control how the image fits its container:
<Image src="https://example.com/photo.jpg" width="100%" height={300} objectFit="cover" />
For better performance and features like blurhash placeholders and transitions,
you can use createImage to create a custom Image component with expo-image:
import { Image as ExpoImage } from 'expo-image'
import { createImage } from '@tamagui/image'
export const Image = createImage({
Component: ExpoImage,
resizeModePropName: 'contentFit',
objectPositionPropName: 'contentPosition',
})
Now you can use all expo-image props alongside Tamagui's unified API:
const blurhash = '|rF?hV%2WCj[ayj[a|j[az...'
export default () => (
<Image
src="https://example.com/photo.jpg"
width={200}
height={300}
objectFit="cover"
placeholder={{ blurhash }}
transition={300}
/>
)
<SimpleTable
headers={['Option', 'Type', 'Default', 'Description']}
rows={[
[
'Component',
'ComponentType',
'-',
'The underlying image component (expo-image, react-native-fast-image, etc.)',
],
[
'resizeModePropName',
'string',
"'resizeMode'",
"The prop name for resize mode. expo-image uses 'contentFit'",
],
[
'objectPositionPropName',
'string',
'undefined',
"The prop name for object position. expo-image uses 'contentPosition'",
],
[
'mapObjectFitToResizeMode',
'function',
'Default mapper',
"Custom function to map objectFit values to the component's resize mode",
],
[
'transformSource',
'function',
'Default transformer',
'Custom function to transform source props',
],
]}
/>
Always provide an alt attribute describing the image content. For decorative images, use an empty string (alt="").
// meaningful image
<Image
src="/team-photo.jpg"
alt="The Tamagui team at React Conf 2024"
width={400}
height={300}
/>
// decorative image
<Image
src="/decorative-bg.jpg"
alt=""
width={400}
height={300}
/>
On React Native, use accessible and accessibilityLabel for screen reader support. See the React Native Accessibility docs for details.
<Image
src="/avatar.jpg"
accessible
accessibilityLabel="User profile photo"
width={64}
height={64}
/>
Extends View with Tamagui props, plus:
<PropsTable
data={[
{
name: 'src',
type: 'string',
description: 'The image URL. Preferred over source for better web alignment.',
},
{
name: 'alt',
type: 'string',
description:
'Alternative text describing the image for accessibility. Use empty string for decorative images.',
},
{
name: 'objectFit',
type: "'cover' | 'contain' | 'fill' | 'none' | 'scale-down'",
description:
'How the image should be resized to fit its container. Maps to CSS object-fit on web and resizeMode on native.',
},
{
name: 'objectPosition',
type: 'string',
description:
'How the image should be positioned within its container. On native, requires expo-image or similar for full support.',
},
{
name: 'source',
type: 'ImageSourcePropType',
description: 'Deprecated. Use src instead.',
},
{
name: 'resizeMode',
type: 'ImageResizeMode',
description: 'Deprecated. Use objectFit instead.',
},
]}
/>
These props pass through to the native `` element on web:
<PropsTable data={[ { name: 'loading', type: "'lazy' | 'eager'", description: 'Lazy load images below the fold. Use eager (default) for above-the-fold images.', }, { name: 'decoding', type: "'async' | 'sync' | 'auto'", description: 'Hint for how the browser should decode the image. Use async for non-blocking decode.', }, { name: 'fetchPriority', type: "'high' | 'low' | 'auto'", description: 'Hint for fetch priority. Use high for LCP (largest contentful paint) images.', }, { name: 'srcSet', type: 'string', description: 'Comma-separated list of image sources with width descriptors for responsive images.', }, { name: 'sizes', type: 'string', description: 'Media conditions describing the image display size, used with srcSet.', }, { name: 'crossOrigin', type: "'anonymous' | 'use-credentials'", description: 'CORS setting for the image request.', }, { name: 'referrerPolicy', type: 'string', description: 'Referrer policy for the image request.', }, ]} />
<PropsTable data={[ { name: 'alt', type: 'string', description: 'Alternative text for screen readers. Required for meaningful images, use empty string for decorative.', }, { name: 'accessible', type: 'boolean', description: 'Native only. Marks the image as an accessible element.', }, { name: 'accessibilityLabel', type: 'string', description: 'Native only. Label read by screen readers. Use with accessible={true}.', }, { name: 'aria-label', type: 'string', description: 'Overrides alt as the accessible name. Prefer using alt instead.', }, { name: 'aria-describedby', type: 'string', description: 'References an element providing extended description.', }, { name: 'aria-hidden', type: 'boolean', description: 'Hides the image from assistive technology. Alternative to alt="".', }, { name: 'role', type: 'string', description: "Set to 'presentation' or 'none' for decorative images, or 'img' (default).", }, ]} />
<Notice theme="green"> Web props like `loading`, `srcSet`, and `fetchPriority` only apply on web. On native, use expo-image via `createImage` for advanced features like blurhash placeholders and priority loading. </Notice>