Skip to main content

Images

note

Images are rendered with an internal renderer. See ​Rendering page. The content model of images is ​block, see ​Element Models. Also note that this renderer covers the ​<img> tag. ​<picture> tag is not yet supported.

Scaling#

Inline Styles#

The renderer will automatically scale images down to the available width, even when the provided inline style width is greater than the container width. You need to activate enableExperimentalPercentWidth for percent-width support in images. See ​RenderersProps.img for reference.

important

You are strongly advised to provide a ​contentWidth property from ​useWindowDimensions official hook to help this component handle the scaling.

Image with inline styles
import React from 'react';
import { useWindowDimensions } from 'react-native';
import RenderHtml from 'react-native-render-html';
const source = {
html: `<img
width="1200" height="800"
style="width: 50%; height: 100px; align-self: center;"
src="http://placeimg.com/1200/800/animals"
/>`
};
const renderersProps = {
img: {
enableExperimentalPercentWidth: true
}
};
export default function App() {
const { width } = useWindowDimensions();
return (
<RenderHtml
contentWidth={width}
source={source}
renderersProps={renderersProps}
/>
);
}
This image dimensions are set with inline styles. Note that both the width/height couple and the style attributes are evaluated, but the style attribute takes precedence. The relative width (50%) is computed against contentWidth.
Press on the button below to show how this code renders on your device.

Object Fit#

This library supports ​object-fit CSS property. In the below example, which is very similar to the previous one, we set explicitly object-fit:Β contain; to letterbox the image in the container of width 50% and height 100px.

Object Fit Support
import React from 'react';
import { useWindowDimensions } from 'react-native';
import RenderHtml from 'react-native-render-html';
const source = {
html: `<img
width="1200" height="800"
style="object-fit: contain; width: 50%; height: 100px; align-self: center;"
src="http://placeimg.com/1200/800/animals"
/>`
};
const renderersProps = {
img: {
enableExperimentalPercentWidth: true
}
};
export default function App() {
const { width } = useWindowDimensions();
return (
<RenderHtml
contentWidth={width}
source={source}
renderersProps={renderersProps}
/>
);
}
Object-fit "cover", "contain", "fill" and "scale-down" values are supported, and will be translated to React Native "resizeMode" style property.
Press on the button below to show how this code renders on your device.
tip

​object-fit is a mixed style and thus you can use it in mixed styles declarations such as ​tagsStyles.

Automatic Sizing#

The next image will be sized automatically thanks to the ​contentWidth and ​computeEmbeddedMaxWidth props. The latter allows you to set the maximum width from ​contentWidth, or disabling scaling by returning ​Infinity.

Image with width and height attributes
import React from 'react';
import { useWindowDimensions } from 'react-native';
import RenderHtml from 'react-native-render-html';
const source = {
html: `<img
width="1200" height="800"
src="http://placeimg.com/1200/800/nature"
/>`
};
export default function App() {
const { width } = useWindowDimensions();
return (
<RenderHtml
contentWidth={width}
source={source}
/>
);
}
This image has no inline style. Its width and height are determined by the width and height attributes, scaled down to fit the result of computeEmbeddedMaxWidth('img').
Press on the button below to show how this code renders on your device.

Preloading#

Similarly to browsers, this library will place a print box before fetching image dimensions when both ​width and ​height attributes are provided, or the two dimensions are set in the ​style attribute. This is great to avoid layout shifts when images size jumps from 0 to the view box height, and is a hint to good web design.

Error Handling#

Unreachable image
import React from 'react';
import { useWindowDimensions } from 'react-native';
import RenderHtml from 'react-native-render-html';
const source = {
html: `<img
width="200" height="100"
alt="The Void"
src="http://example.tld/image.jpg"
/>`
};
export default function App() {
const { width } = useWindowDimensions();
return (
<RenderHtml
contentWidth={width}
source={source}
/>
);
}
When an image is unreachable, the image renderer will print a box while preserving its requested dimensions. It will also display at the center of the box the content of alt attribute.
Press on the button below to show how this code renders on your device.

Custom Renderer#

tip

You are kindly advised to read the ​Custom Rendering page before continuing.

Via useInternalRenderer#

​useInternalRenderer has a great advantage over using ​InternalRenderer prop: you have access to the internal component props. In this scenario, we are going to display an interactive thumbnail which will show the full resolution image when pressed. To do so, we are going to read the URI from the internal source prop (although we could also do this from the ​TNode src ​attributes), and mangle it to get our "thumbnail" URI.

A Custom Image Renderer based on useInternalRenderer
import { useWindowDimensions, Modal, Button, Text, View } from 'react-native';
import React, { useState } from 'react';
import RenderHtml, { useInternalRenderer } from 'react-native-render-html';
function CustomImageRenderer(
props
) {
const { Renderer, rendererProps } = useInternalRenderer('img', props);
const [isModalOpen, setIsModalOpen] = useState(false);
const onPress = () => setIsModalOpen(true);
const onModalClose = () => setIsModalOpen(false);
const uri = rendererProps.source.uri;
const thumbnailSource = {
...rendererProps.source,
// You could change the uri here, for example to provide a thumbnail.
uri: uri.replace('1200', '300').replace('800', '200')
};
return (
<View style={{ alignItems: 'center' }}>
<Renderer {...rendererProps} source={thumbnailSource} onPress={onPress} />
<Modal visible={isModalOpen} onRequestClose={onModalClose}>
<Renderer {...rendererProps} />
<Text>A full resolution image!</Text>
<Button title="Close Modal" onPress={onModalClose} />
</Modal>
</View>
);
}
const source = {
html: '<img src="https://dummyimage.com/1200x800">'
};
const tagsStyles = {
img: {
alignSelf: 'center'
}
};
const renderers = {
img: CustomImageRenderer
};
export default function App() {
const { width } = useWindowDimensions();
return (
<RenderHtml
contentWidth={width}
source={source}
tagsStyles={tagsStyles}
renderers={renderers}
/>
);
}
Press the image and a modal will appear!
Press on the button below to show how this code renders on your device.

By Reusing Internal Building Blocks#

You can reuse to your advantage some building blocks of the internal renderer thanks to the following exports:

​IMGElementContainer

To render the container of the ​<img> element.

​IMGElementContentError

To render the fallback view on error state.

​IMGElementContentLoading

To render the fallback view on loading state.

​IMGElementContentSuccess

To render the image on success state..

​useIMGElementState

To get the state of the image resource fetching.

In the below example, our custom renderer will display an activity indicator when the state is either "loading" or "success". This is for demonstration purposes, and of course you should handle the "success" state by rendering the ​IMGElementContentSuccess component, or a custom component displaying an image.

A Custom Tag Example
import React from 'react';
import { useWindowDimensions, View, ActivityIndicator } from 'react-native';
import RenderHtml, { IMGElementContainer, IMGElementContentError, IMGElementContentSuccess, useIMGElementProps, useIMGElementState } from 'react-native-render-html';
function IMGElementContentLoading({ dimensions, altColor }) {
const loadingStyles = { justifyContent: 'center', alignItems: 'center' };
return (
<View style={[dimensions, loadingStyles]}>
<ActivityIndicator color={altColor} size="large" />
</View>
);
}
function CustomImageRenderer(
props
) {
const imgElementProps = useIMGElementProps(props);
const state = useIMGElementState(imgElementProps);
let content: ReactNode = false;
if (state.type === 'error') {
content = React.createElement(IMGElementContentError, state);
} else {
content = React.createElement(IMGElementContentLoading, state);
}
return (
<IMGElementContainer
onPress={imgElementProps.onPress}
style={state.containerStyle}>
{content}
</IMGElementContainer>
);
}
const source = {
html: '<img src="http://placeimg.com/1200/800/architecture">'
};
const renderers = {
img: CustomImageRenderer
};
export default function App() {
const { width } = useWindowDimensions();
return (
<RenderHtml
contentWidth={width}
source={source}
renderers={renderers}
/>
);
}
A Custom image renderer which renders a spinner on "loading" and "success" states.
Press on the button below to show how this code renders on your device.

Configuring#

Providing headers#

You can take advantage of the ​provideEmbeddedHeadersprop to pass headers to the image fetching conditionnaly. For example:

Providing headers to images
import React from 'react';
import RenderHtml from 'react-native-render-html';
import { useWindowDimensions, Platform, PixelRatio } from 'react-native';
function provideEmbeddedHeaders(uri, tagName) {
if (tagName === 'img') {
return {
Authorization: "Bearer XYZ",
};
}
}
const source = {
html: '<img src="https://www.fillmurray.com/200/100" />'
};
export default function App() {
const { width } = useWindowDimensions();
return (
<RenderHtml
contentWidth={width}
source={source}
provideEmbeddedHeaders={provideEmbeddedHeaders}
/>
);
}
provideEmbeddedHeaders lets you pick headers for specific domains and works with multiple tags. For example, it can be used with the iframe plugin.
Press on the button below to show how this code renders on your device.
tip

In this example, we are using a Bearer token to access a restricted resource. We could also use headers to take advantage of the new Responsive Image Client Hints standard.

Advanced configuration#

We can take advantage of the ​renderersProps to customize images behavior (see ​RenderersProps.img).