necolas/react-native-web · error · Error
The <Image> component cannot contain children. If you want t
Error message
The <Image> component cannot contain children. If you want to render content on top of the image, consider using the <ImageBackground> component or absolute positioning.
What it means
HTML/CSS cannot reliably render nested content inside an <img>-backed element the way native UIImageView+subviews can, so react-native-web forbids children on <Image>. The library provides <ImageBackground> (which renders a wrapper with the image as a child layer) for overlaying content. The check only runs in development (NODE_ENV !== 'production').
Source
Thrown at packages/react-native-web/src/exports/Image/index.js:199
accessibilityLabel,
blurRadius,
defaultSource,
draggable,
onError,
onLayout,
onLoad,
onLoadEnd,
onLoadStart,
pointerEvents,
source,
style,
...rest
} = props;
const ariaLabel = _ariaLabel || accessibilityLabel;
if (process.env.NODE_ENV !== 'production') {
if (props.children) {
throw new Error(
'The <Image> component cannot contain children. If you want to render content on top of the image, consider using the <ImageBackground> component or absolute positioning.'
);
}
}
const [state, updateState] = React.useState(() => {
const uri = resolveAssetUri(source);
if (uri != null) {
const isLoaded = ImageLoader.has(uri);
if (isLoaded) {
return LOADED;
}
}
return IDLE;
});
const [layout, updateLayout] = React.useState({});
const hasTextAncestor = React.useContext(TextAncestorContext);View on GitHub (pinned to a9de220ba9)
Solutions
- Replace <Image> with <ImageBackground> when children are needed.
- Or position the overlay outside the Image with absolute positioning inside a wrapper View.
- If no children are intended, remove the stray JSX inside <Image>.
Example fix
// before
<Image source={img}><Text>Hi</Text></Image>
// after
<ImageBackground source={img}>
<Text>Hi</Text>
</ImageBackground> Defensive patterns
Strategy: validation
Validate before calling
function assertNoImageChildren(props) {
if (process.env.NODE_ENV !== 'production' && props.children != null) {
throw new Error('Use <ImageBackground> instead of <Image> with children.');
}
} Type guard
const needsImageBackground = (children) => children != null;
Try / catch
try { return <Image {...props} />; } catch (e) { if (/cannot contain children/.test(e.message)) return <ImageBackground {...props} />; throw e; } Prevention
- Default to <ImageBackground> whenever overlay content is needed
- Add a lint rule/ESLint plugin to flag children inside <Image>
- Review RN->web ports for legacy <Image> nesting
When it happens
Trigger: Rendering any children inside <Image> in a non-production build, e.g. <Image source={...}><Text>label</Text></Image>.
Common situations: Migrating code from React Native where placing children in Image was tolerated or common before RN deprecated it; adding badges/overlays on top of avatars; following old RN tutorials.
Related errors
- Image: asset with ID "${source}" could not be found. Please
- StyleSheet.compose() only accepts 2 arguments, received ${le
- Invalid CSS keyframes type: ${typeof keyframesValue}
- Unrecognized signal `${signal}` or state `${curState}` for T
- Touchable cannot transition from `${curState}` to `${signal}
AI-assisted analysis of necolas/react-native-web@a9de220ba9 (2026-09-01).
Data as JSON: /api/errors/4021d6a5a3debca2.
Report an issue: GitHub.