Components / Media

Image

Image is the picture primitive. On its own it is a styled <img>; give it a placeholder or a fallback and it grows a wrapper that shows the right overlay while the image loads or after it fails.

Loading playground…
Updated 3 days agoEdit on GitHubWeb & native

What it is

A two-mode component. With no placeholder and no fallback, Image emits a plain styled <img> — every Box style prop applies straight to the element. Set either overlay and Image switches to the wrapped mode: a relatively-positioned Box holds the <img>, the overlay sits absolutely on top, and the image fades in once loaded.

The placeholder shows during loading; the fallback shows on error. When no fallback is set, the placeholder also covers the error state.

Install

Image is exported from usemotif. No separate install.

example.tsx
import { Image } from 'usemotif';

API

Image

stable
function Image(props: ImageProps): JSX.Element
srcstringrequired

Image URL.

altstringrequired

Alt text. Pass an empty string for a purely decorative image — a deliberate choice, not an omission.

placeholderReactNode

Rendered over the image while it loads. A coloured Box, a skeleton, a blur-up — any node.

fallbackReactNode

Rendered if the image fails to load. Falls back to `placeholder` when omitted.

loading"lazy" | "eager"

The `<img>` loading attribute.

srcSet / sizesstring

Responsive-image attributes — passed through to the `<img>`.

onLoad / onError(event) => void

Load and error callbacks. Fire alongside the internal state transitions.

…BoxPropsOmit<BoxProps, "children">

Every Box style prop. In simple mode they land on the `<img>`; in wrapped mode the size and box styles land on the wrapper.

Accessibility

alt is required. A meaningful image gets a description of what it shows; a decorative image gets an empty string, which tells assistive technology to skip it. Both are valid — the point is that the choice is explicit. There is no Image without an alt decision.

Examples

Simple styled image:

example.tsx
<Image
src="/cover.jpg"
alt="Mountain ridge at dawn"
w={320}
h={200}
borderRadius="$radii.md"
objectFit="cover"
/>

With a placeholder and a fallback:

example.tsx
<Image
src={photo.url}
alt={photo.caption}
w={240}
h={160}
placeholder={<Box bg="$colors.surface.muted" w="100%" h="100%" />}
fallback={<Center bg="$colors.surface.muted" w="100%" h="100%">Unavailable</Center>}
/>

A decorative image — empty alt:

example.tsx
<Image src="/texture.png" alt="" w="100%" h={120} />

Cross-platform notes

On web Image renders an <img>. On native it renders through the React Native image primitive; the loading, decoding, srcSet, and sizes attributes are web-only and ignored. The placeholder / fallback overlay model works on both platforms.