Avoid Pitfalls when Using Images in React

June 21, 2022

3 min read

Michael P.

Michael P. McAuliffe

Which module loading solution works best for your situation?

pitfall-player-dead








When React code is transpiled into browser-readable javascript, JSX goes through a few transformations before it is seen in the browser. Build directories are restructured and files are indexed differently in production. This transformation exposes the possibility of hazards when dealing with different types of modules.

Developers use toolchains such as Create React App (CRA), and Next.js use Webpack as a bundler to assist with module integration. There are minor differences between versions of Webpack and CRA that affect the src attribute in an image tag. Aside from those minor tweaks, there are 3 main ways to utilize an image in React.

  • Import an image as a module
  • Require an image inline
  • Accessing images in the public directory, the 'escape hatch'





Import an Image as a Module

Once the image is imported, the imported variable can be set as the value of the src attribute in an image tag.

1import beautifulMountians from './images/beautifulMountians.jpg';
2
3const FavoriteImages = () => (
4 <>
5 <p>My Favorite Mountian!</p>
6
7 <img
8 alt='beautiful-mount'
9 src={beautifulMountians} />
10 </>
11);
12
13export default FavoriteImages;


My Favorite Mountian!

image-1


Considerations for Importing an Image

This is an easy way to display an image, but this wouldn't be practical for importing many images. This method also has limitations for displaying images dynamically. There are other solutions to these problems coming up.






Require an image inline

1const FavoriteImages = () => (
2 <>
3 <p>My Favorite Mountian!</p>
4
5 <img
6 alt='beautiful-mount'
7 src={require('./images/beautifulMountians.jpg')} />
8 </>
9);
10
11export default FavoriteImages;


There may be issues using require in this way. Specific to older versions of react scripts, you may need to reference the .default key. You can read more about this issue here.

1<img
2 alt='beautiful-mount'
3 src={require('./images/beautifulMountians.jpg').default} />


You Actually CAN Import Multiple Images

Javascript modules are robust so there are many ways they can be used to overcome challenges. The power of import can be combined with the power of require. Take this file tree, for instance:

1├── src/
2 ├── images/
3 │ ├── bear1.jpg
4 │ ├── bear2.jpg
5 │ └── index.js
6 ├── App.js
7 └── …

Images can be exported as an object in images/index.js

1// index.js
2 const images = {
3 bear1: require('../images/bear1.jpg'),
4 bear2: require('../images/bear2.jpg'),
5 }
6
7 export default images


The images object may now be imported in App.js.

1import images from './images';
2
3const FavoriteImages = () => (
4 <>
5 <p>BEARS!</p>
6
7 <img
8 alt='bear1'
9 src={images.bear1} />
10 <img
11 alt='bear2'
12 src={images.bear2} />
13 </>
14);
15
16export default FavoriteImages;

Bears!

image-1
image-2





Using the Public Directory — The Escape Hatch

This option works with CRA and Next.js. CRA refers to this as an escape hatch and emphasizes that it should be used rarely. The file tree may be different in your app, but the premise is the same.

1├── public/
2 ├── images/
3 └── spookyTown.jpg
4├── scr/
5 ├── App.js
6 └── …

The public directory can be accessed using the process.env.PUBLIC_URL environment variable.

1const FavoriteImages = () => (
2 <>
3 <p>Spooky Town</p>
4
5 <img
6 alt='spooky-town'
7 src={process.env.PUBLIC_URL + '/images/spookyTown.jpg'} />
8 </>
9);
10
11export defualt FavoriteImages;

Spooky Town

image-1





hexAscent

More Blogs


Jazz-Up Your Buttons with Gradients

June 1, 2022

thumbnail