Back to Tamagui

Image

code/tamagui.dev/data/docs/components/image/2.0.0.mdx

1.144.46.8 KB
Original Source
<HeroContainer noPad> <ImageDemo /> </HeroContainer>
tsx

<Highlights features={[ 'Supports SSR.', 'Works on native and web.', 'Accepts Tamagui style props.', 'Pluggable architecture with createImage for expo-image and more.', ]} />

Installation

Image is already installed in tamagui, or you can install it independently:

bash
npm install @tamagui/image

Usage

Use the src prop for the image URL:

tsx
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:

tsx
<Image src="https://example.com/photo.jpg" width="100%" height={300} objectFit="cover" />

Using with expo-image

For better performance and features like blurhash placeholders and transitions, you can use createImage to create a custom Image component with expo-image:

tsx
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:

tsx
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}
  />
)

createImage Options

<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', ], ]} />

Accessibility

Always provide an alt attribute describing the image content. For decorative images, use an empty string (alt="").

tsx
// 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.

tsx
<Image
  src="/avatar.jpg"
  accessible
  accessibilityLabel="User profile photo"
  width={64}
  height={64}
/>

API Reference

Image

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.', }, ]} />

Web-only Props

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.', }, ]} />

Accessibility Props

<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>