|
| 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"> </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> |
0 commit comments