Skip to content

Commit 8b6536c

Browse files
committed
Document React-specific img behavior
1 parent f7f4524 commit 8b6536c

3 files changed

Lines changed: 263 additions & 1 deletion

File tree

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
---
2+
title: "<img>"
3+
---
4+
5+
<Intro>
6+
7+
The [built-in browser `<img>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img) lets you embed an image.
8+
9+
```js
10+
<img src="photo.jpg" alt="A person walking through a park" />
11+
```
12+
13+
</Intro>
14+
15+
<InlineToc />
16+
17+
---
18+
19+
## Reference {/*reference*/}
20+
21+
### `<img>` {/*img*/}
22+
23+
To display an image, render the [built-in browser `<img>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img).
24+
25+
```js
26+
<img src="photo.jpg" alt="A person walking through a park" />
27+
```
28+
29+
[See more examples below.](#usage)
30+
31+
#### Props {/*props*/}
32+
33+
`<img>` supports all [common element props.](/reference/react-dom/components/common#common-props)
34+
35+
* `alt`: a string. Specifies alternative text for the image. Use an empty string for a purely decorative image.
36+
* `crossOrigin`: a string. Specifies the [CORS policy](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin) to use when fetching the image. The possible values are `anonymous` and `use-credentials`.
37+
* `decoding`: a string. Suggests whether the browser should wait to decode the image before presenting other content. The possible values are `async`, `sync`, and `auto` (the default).
38+
* `fetchPriority`: a string. Suggests a relative priority for fetching the image. The possible values are `high`, `low`, and `auto` (the default). During server rendering, `fetchPriority="low"` also prevents React from [automatically preloading the image.](#controlling-image-preloading-during-server-rendering)
39+
* `height`: a number or string. Specifies the rendered height of the image.
40+
* `loading`: a string. Specifies whether the browser should defer loading the image until it is near the viewport. The possible values are `eager` (the default) and `lazy`. Setting `loading="lazy"` prevents React from [automatically preloading the image.](#controlling-image-preloading-during-server-rendering)
41+
* `onError`: an [event handler](/reference/react-dom/components/common#event-handler) function. Fires when the image fails to load.
42+
* `onLoad`: an [event handler](/reference/react-dom/components/common#event-handler) function. Fires when the image finishes loading. Passing `onLoad` prevents React from [waiting for the image during a client-rendered View Transition update.](#waiting-for-an-image-during-a-view-transition)
43+
* `referrerPolicy`: a string. Specifies the [referrer information](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#referrerpolicy) to send when fetching the image.
44+
* `sizes`: a string. Specifies the image sizes for different page layouts. Used with `srcSet`.
45+
* `src`: a string. Specifies the URL of the image.
46+
* `srcSet`: a string. Specifies one or more candidate image sources for the browser to choose from.
47+
* `useMap`: a string. Associates the image with a [client-side image map](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/map).
48+
* `width`: a number or string. Specifies the rendered width of the image.
49+
50+
#### Caveats {/*caveats*/}
51+
52+
* Do not pass an empty string to `src`. React warns in development and omits the attribute. To render no image, omit the `<img>` or pass `null` to `src`.
53+
* `<img>` cannot have children or use `dangerouslySetInnerHTML`. React throws an error if you pass either.
54+
* `fetchPriority="low"` does not stop React from waiting for the image to load and decode during a client-rendered View Transition update. Use `loading="lazy"` or an `onLoad` handler to opt out of that behavior.
55+
56+
---
57+
58+
## Usage {/*usage*/}
59+
60+
### Displaying an image {/*displaying-an-image*/}
61+
62+
Pass the image URL to `src` and a text description to `alt`:
63+
64+
<Sandpack>
65+
66+
```js
67+
export default function Profile() {
68+
return (
69+
<img
70+
src="https://react.dev/images/docs/scientists/yXOvdOSs.jpg"
71+
alt="Hedy Lamarr"
72+
width={100}
73+
height={100}
74+
/>
75+
);
76+
}
77+
```
78+
79+
```css
80+
img {
81+
border-radius: 50%;
82+
object-fit: cover;
83+
}
84+
```
85+
86+
</Sandpack>
87+
88+
Specify `width` and `height` when you know the image dimensions so the browser can reserve space before the image loads. For a decorative image, pass `alt=""` so that screen readers ignore it.
89+
90+
---
91+
92+
### Controlling image preloading during server rendering {/*controlling-image-preloading-during-server-rendering*/}
93+
94+
During server rendering, React automatically generates a preload hint for an `<img>` by default. This can let the browser start fetching the image before it encounters the `<img>` in the rendered HTML.
95+
96+
Add `loading="lazy"` or `fetchPriority="low"` to an image that should not receive this hint:
97+
98+
```js
99+
function ProductPage() {
100+
return (
101+
<>
102+
<img src="hero.jpg" alt="Featured product" />
103+
<img src="thumbnail.jpg" alt="Related product" loading="lazy" />
104+
<img src="secondary.jpg" alt="Another product" fetchPriority="low" />
105+
</>
106+
);
107+
}
108+
```
109+
110+
In this example, React generates a preload hint only for `hero.jpg`. Depending on the server API or framework, React may render the equivalent of this element:
111+
112+
```html
113+
<link rel="preload" as="image" href="hero.jpg" />
114+
```
115+
116+
React may instead provide the same hint in a `Link` response header. The other two images keep their `loading` and `fetchPriority` props in the rendered HTML, but React does not generate preload hints for them. The `loading="lazy"` prop asks the browser to defer loading an image until it approaches the viewport. The `fetchPriority="low"` prop allows the image to load immediately, but tells the browser to fetch it at a lower priority.
117+
118+
React also does not automatically preload an image when it is inside a `<picture>` or `<noscript>` element, or when its `src` or `srcSet` is a data URL.
119+
120+
If you render an image through a framework or a component library, consult its documentation for the default behavior. React decides whether to generate an automatic preload from the props of the underlying `<img>`. For example, an image component may add `loading="lazy"` by default and provide a separate option for explicitly preloading selected images.
121+
122+
To create an explicit preload hint, call [`preload`](/reference/react-dom/preload).
123+
124+
---
125+
126+
### Waiting for an image during a View Transition {/*waiting-for-an-image-during-a-view-transition*/}
127+
128+
During a client-rendered [`<ViewTransition>`](/reference/react/ViewTransition) update, React may wait for an image to load and decode before starting the animation. This applies when a new `<img>` with a non-empty `src` is rendered, or when an existing image's `src` or `srcSet` changes. The image must be inside the `<ViewTransition>` subtree and must not have `loading="lazy"` or an `onLoad` handler. React does not wait for images during synchronous updates.
129+
130+
When a Suspense boundary reveals streamed content inside a `<ViewTransition>`, React may also wait for visible images with a non-empty `src` that do not have `loading="lazy"`. React stops waiting after a timeout so that a slow image does not block the update indefinitely.
131+
132+
In this example, the Suspense boundary is wrapped in a `<ViewTransition>` and shows a profile skeleton until the portrait has loaded.
133+
134+
For comparison, the second button inserts the same card directly into the DOM. The card appears immediately, and the browser displays the image after it loads:
135+
136+
<Sandpack>
137+
138+
```js
139+
import { ViewTransition, Suspense, useState, startTransition } from 'react';
140+
import { freshImageUrl } from './image.js';
141+
import VanillaProfile from './VanillaProfile.js';
142+
143+
function Profile({ src }) {
144+
return (
145+
<div className="card">
146+
<img src={src} alt="Jack Pope" width={80} height={80} />
147+
<p>Jack Pope</p>
148+
</div>
149+
);
150+
}
151+
152+
function ProfilePlaceholder() {
153+
return (
154+
<div className="card">
155+
<div className="avatar-placeholder" />
156+
<p className="name-placeholder">&nbsp;</p>
157+
</div>
158+
);
159+
}
160+
161+
export default function App() {
162+
const [src, setSrc] = useState(null);
163+
return (
164+
<>
165+
<button
166+
onClick={() => {
167+
startTransition(() => {
168+
setSrc(freshImageUrl());
169+
});
170+
}}>
171+
Show profile
172+
</button>
173+
{src && (
174+
<ViewTransition>
175+
<Suspense fallback={<ProfilePlaceholder />}>
176+
<Profile src={src} />
177+
</Suspense>
178+
</ViewTransition>
179+
)}
180+
<hr />
181+
<VanillaProfile />
182+
</>
183+
);
184+
}
185+
```
186+
187+
```js src/VanillaProfile.js
188+
import { useRef } from 'react';
189+
import { freshImageUrl } from './image.js';
190+
191+
export default function VanillaProfile() {
192+
const ref = useRef(null);
193+
function show() {
194+
ref.current.innerHTML = `<div class="card">
195+
<img src="${freshImageUrl()}" alt="Jack Pope" width="80" height="80" />
196+
<p>Jack Pope</p>
197+
</div>`;
198+
}
199+
return (
200+
<>
201+
<button onClick={show}>Show profile (direct DOM update)</button>
202+
<div ref={ref} />
203+
</>
204+
);
205+
}
206+
```
207+
208+
```js src/image.js hidden
209+
// Add a unique parameter so the image isn't cached,
210+
// and every run shows the loading state.
211+
export function freshImageUrl() {
212+
return 'https://react.dev/images/team/jack-pope.jpg?t=' + Date.now();
213+
}
214+
```
215+
216+
```css
217+
#root {
218+
min-height: 390px;
219+
}
220+
.card {
221+
margin-top: 1em;
222+
}
223+
.card img {
224+
display: block;
225+
border-radius: 50%;
226+
background: #dfe3e9;
227+
}
228+
.card p {
229+
font-weight: bold;
230+
}
231+
.avatar-placeholder {
232+
width: 80px;
233+
height: 80px;
234+
border-radius: 50%;
235+
background: #dfe3e9;
236+
}
237+
.name-placeholder {
238+
width: 90px;
239+
border-radius: 4px;
240+
background: #dfe3e9;
241+
}
242+
hr {
243+
margin: 16px 0;
244+
}
245+
```
246+
247+
```json package.json hidden
248+
{
249+
"dependencies": {
250+
"react": "19.3.0",
251+
"react-dom": "19.3.0",
252+
"react-scripts": "latest"
253+
}
254+
}
255+
```
256+
257+
</Sandpack>

src/content/reference/react-dom/components/index.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ They are special in React because passing the `value` prop to them makes them *[
3636

3737
These built-in browser components let you load external resources or annotate the document with metadata:
3838

39+
* [`<img>`](/reference/react-dom/components/img)
3940
* [`<link>`](/reference/react-dom/components/link)
4041
* [`<meta>`](/reference/react-dom/components/meta)
4142
* [`<script>`](/reference/react-dom/components/script)
@@ -91,7 +92,7 @@ React supports all built-in browser HTML components. This includes:
9192
* [`<html>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/html)
9293
* [`<i>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/i)
9394
* [`<iframe>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe)
94-
* [`<img>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img)
95+
* [`<img>`](/reference/react-dom/components/img)
9596
* [`<input>`](/reference/react-dom/components/input)
9697
* [`<ins>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ins)
9798
* [`<kbd>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/kbd)

src/sidebarReference.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,10 @@
220220
"title": "<textarea>",
221221
"path": "/reference/react-dom/components/textarea"
222222
},
223+
{
224+
"title": "<img>",
225+
"path": "/reference/react-dom/components/img"
226+
},
223227
{
224228
"title": "<link>",
225229
"path": "/reference/react-dom/components/link"

0 commit comments

Comments
 (0)