Carl Rippon

Building SPAs

Carl Rippon
BlogBooks / CoursesAbout
This site uses cookies. Click here to find out more

Using images in React and TypeScript with Webpack 5

February 03, 2021
reacttypescript

In the last post, we added CSS to our Webpack configuration for our React and TypeScript app. In this post, we will extend this Webpack configuration so that images can be used in the app.

Referencing an image in the app

Let’s try to reference an image in a component as follows:

const Content = () => (
  <div>
    <img src="./car.jpg" className={content.car} />
  </div>
);

If we run the app in dev mode (npm start), we see that the image isn’t found:

Image error

At the moment, Webpack isn’t moving or doing anything with the image when the code is bundled.

Let’s try importing the image. Perhaps, Webpack will then be aware of the image and handle it?

import car from "./car.jpg";
...
const Content = () => (
  <div>
    <img src={car} className={content.car} />
  </div>
);

We get a TypeScript error:

TypeScript image error

We had a similar error with css files in the last post. To resolve this error, we can add the following content into a file called custom.d.ts in the src folder:

declare module "*.jpg";
declare module "*.png";
declare module "*.jpeg";
declare module "*.gif";

TypeScript will now be happy with a range of image files. However, Webpack is still struggling to handle our car image:

Webpack image error

Configuring Webpack to handle images

We can tell Webpack to handle images using its new (in v5) built-in asset module

const config: webpack.Configuration = {
  ...
  module: {
    rules: [
      ...,
      {
        test: /\.(png|jpg|jpeg|gif)$/i,
        type: "asset/resource",
      },
    ],
  },
  ...
};

We add the above rule for the production Webpack configuration as well as development.

In dev mode (npm start), the app now successfully renders the image:

Image in development

Notice how Webpack has given the image a random looking name during the bundling process. This means that the file name doesn’t clash with other image files in other components.

In a production build (npm run build), we see that the image is moved to the build folder with the random looking name and is referenced accordingly in the JavaScript:

Image in production build

Handling image references in CSS

We may want to reference images in CSS. Let’s check that this works ok.

We will apply some CSS to the container div in the Content component:

const Content = () => (
  <div className={content.container}>    <img src={car} className={content.car} />
  </div>
);

This CSS will contain a background image:

.container {
  background-image: url("./background.jpg");
  width: 400px;
  height: 300px;
  background-size: cover;
}

In dev mode, the background is handled fine:

Background image in development

In the production build, the background is also handled nicely:

Background image in production

Excellent! 😊

That’s it! Our React and TypeScript project is now set up to use images.

This code is available in GitHub at https://github.com/carlrip/react-typescript-images-webpack.

Did you find this post useful?

Let me know by sharing it on Twitter.
Click here to share this post on Twitter

If you to learn more about using TypeScript with React, you may find my course useful:

Using TypeScript with React

Find out more