In React, image tags are a bit weird. This isn’t really React’s fault, but more a problem of where the images will reside on the server after the app is built.
I’m talking about the plain old <img src=""/>
tag here. The same one you’d use in HTML.
When you img
in a React component, the the src
prop needs to be point at something that the server can serve.
Don’t Use a File Path From Your Computer
A common mistake for beginners is to set the src
to a file path on their computer, like /Users/yourname/Projects/this-react-app/src/image.png
. That won’t work.
Browsers are mostly sandboxed these days and won’t let you access files by their path on disk. If you did get that to work (maybe with file://
), it’d break as soon as you deployed the app, because a web server won’t have that file in the same place! (And no, the solution is not to put it in the same place on the server :)
Two Ways to Include an Image in a React Component
With React, since there’s a build step, you need a way to include the image. There are 2 main ways to do that.
I’m going to assume a Create React App project here, where everything in the public
directory gets copied to the server and everything under src
is fair game for importing into JS files.
Option 1: import
the image into the component
Put the image file somewhere under the src
folder. This alone will not automatically make it available, so you have to import the image into the React component where you’re using it.
import companyLogo from './path/to/logo.jpg';
Then you can reference it by that variable name. The name can be anything you want, it doesn’t have to match the image or anything.
Wherever you want to display the image, render your img
tag and pass that variable as the src
:
function Home() {
return (
<div>
<img src={companyLogo} alt="BigCo Inc. logo"/>
</div>
);
}
Note I’m using src={companyLogo}
and not src="companyLogo"
! If you use the quoted string "companyLogo"
it will try to fetch a file at /companyLogo
and that will fail. Make sure to use curly braces if you’re using an imported image. Curly braces are the way to pass JS variables as props.
Option 2: Put the image in the public
directory
You can put the image file in the public
folder (or if this is not Create React App… then any folder that will be copied to the server).
Then, assuming your server is treating the public folder as the “root” directory (/
), then your images will be available relative to that – just like with plain HTML.
So if you had an image at public/images/thing.jpg
, you could display that image this way:
function Home() {
return (
<div>
<img src="images/logo.jpg" alt="BigCo Inc. logo"/>
</div>
);
}
Because this method makes the image available as a regular file on the web server, and you can test it by opening http://localhost:3000/images/logo.jpg
in the browser (or, you know, your actual domain name, once it’s deployed!)
How Imported Images Work in React
First, know that import
s are not handled by React at all – they’re handled by your bundler, which is probably Webpack. (if you’re using Create React App, it is definitely Webpack)
Webpack, Rollup, Parcel, and other bundlers all work conceptually the same way: when you import
a static file, like an image or a CSS file, the bundler doesn’t literally paste that file in at the import
location. Instead, it makes a note that this particular JS file depends on this particular image/CSS file/whatever.
Then the bundler will copy the image to the output directory with a generated unique name (like a5c8d3f89cad.jpg
) and, behind the scenes, it will replace <img src={yourName}/>
with <img src="a5c8d3f89cad.jpg"/>
.
If the image is especially small, Webpack might even decide to inline it into the JS bundle, as an optimization.
This all happens without you having to worry about it.
The Best Way to Use the img
tag in React?
For one-off images that are related to the component at hand, I like to import them. Imported images have the side benefit that, if the file is missing, the build will fail, and you’ll find out quick! For that reason, I lean toward importing an image if I’m going to use it.
For generic site-wide images, or where it would be annoying to manually import them, I’ll put them in public. This is especially useful when the React app is only a small slice of your overall site, and the same image should be used by both React and other non-React pages. In this case I’d rather avoid duplicating images (with the potential that the copies get out of sync).