Using images in React and TypeScript with Webpack 5
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:
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:
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:
Configuring Webpack to handle images
We can tell Webpack to handle images using its new (in v5) built-in asset module
const config: 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:
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:
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:
In the production build, the background is also handled nicely:
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.If you to learn more about using TypeScript with React, you may find my course useful: