Implementing images using Next.js Image Component

Emmanuel Ugwu

Responsive images are essential in the modern-day as this improves the appearance of websites on devices with both large and small displays. They are vital because they enable us to serve the right image for the correct screen size, improve user experience, and reduce loading time.

This article utilizes the Next.js Image component to serve responsive images. It comes with multiple built-in performance features to deliver optimal web vitals.

CodeSandbox and Github

The completed project is on CodeSandbox, and you can fork it to get started quickly.

You can also find the source code on Github.

Prerequisites

To follow the steps in this article, you should have:

  • Basic knowledge of CSS, JavaScript, and React.js.
  • Installed the most recent version of Node.js.
  • Terminal such as Git bash(Windows) or ITerm2(MacOS).

Installing the project dependencies

We create a Next.js app in a new folder called responsive-image-app by running the following command in our terminal:

1npx create-next-app responsive-image-app

Next, we’ll navigate into the project directory.

1cd responsive-image-app

Running npm run dev starts the project on the local development server at localhost:3000 in our browser.

What is Next.js Image Component?

The Next.js Image component, next/image, extends the HTML img element. It comes with several built-in performance enhancements to assist us in achieving good Core Web Vitals. These scores are a crucial indicator of our website's user experience, and they are taken into account by Google when determining search rankings.

Some of the optimizations built into the Image component include:

  • Improved Performance: Always deliver images of the correct size for each device, using updated image formats.
  • Visual Stability: Prevent an unexpected shift layout as the page loads automatically
  • Faster Page Loads: The images load when they enter the viewport, with blur-up placeholders as an option.
  • Asset Flexibility: Resize photos stored on remote servers on the fly

How to use Next.js Image Component

To use the Next.js Image Component, import it at the top of the home page on pages/index.js:

1import Image from 'next/image'

Then, we’ll render any two random local images from our computer. The local image files titled sunset.jpg and snow.jpg are in the project’s public directory. Several attributes are similar between using the Next.js Image Component and using the img tag in HTML. There are a few required attributes:

  • src: This is the path to the image.
  • alt: This specifies the alternate text for an image.
  • width: This specifies the width of the image in pixels.
  • height: This specifies the height of the image in pixels.

Let's replace the existing content of the home page with:

1<div className={styles.container}>
2 <h1 className={styles.title}>
3 Responsive images using Next JS Image Component
4 </h1>
5
6 <div className={styles.imagecontainer}>
7 <Image src="/sunset.jpg" alt="Sunset" width={650} height={380} />
8 <Image src="/snow.jpg" alt="Sunset" width={650} height={380} />
9 </div>
10 </div>

Making our Next.js images responsive

One of the Image Component's vital props is the layout prop. A viewport is the user's visible area of a web page. We can tell Next.js how to display the images as the viewport changes in size. The layout prop has four options which are:

  • fixed: The image is not scalable. The image's width and height are specified regardless of the device's size displayed.
  • intrinsic: The image scales down to fit the container's width on smaller viewports. The image does not scale up beyond its actual size on a larger viewport. The container width is set to 100%.
  • responsive: On different viewports, the image is scaled down or up depending on the container's width while retaining the aspect ratio.
  • fill: Stretches the image's width and height to fill the parent container.

We'll set the layout prop to responsive and add it to the Image Component:

1<div className={styles.imagecontainer}>
2 <Image src="/sunset.jpg" alt="Sunset" width={650} height={380} layout="responsive"/>
3 <Image src="/snow.jpg" alt="Sunset" width={650} height={380} layout="responsive"/>
4 </div>

For a better experience, let’s display the images in a grid layout by styling the images container. The CSS Grid Layout offers a grid-based system with rows and columns, making it easier to design web pages without having to use floats and positioning. In the CSS file — style/Home.module.css, we’ll add the code snippet below.

1.imagecontainer {
2 display: grid;
3 grid-template-columns: 2fr 2fr;
4 column-gap: 2rem;
5 }

Using grid-template-columns, the images are aligned side by side as columns with a spacing of 2rem. The Next.js app will look like this after making it responsive:

Looking at the source page for our project, Next.js dynamically sets the srcset attribute to load different images at different sizes depending on the viewport size. Ideally, we would like to serve images adjusted to fit the user's viewport dimensions. Without a way to achieve this, we'll have to supply a larger image than is required. That means the browser will be able to load different image sizes depending on the size of the browser or screen size. So, if a visitor is using a small device, they won't have to load the same large images as a desktop.

We’ll also style the image container to stack our images on one another when it is displayed on a smaller screen.

1@media (max-width: 425px) {
2 .imagecontainer {
3 display: grid;
4 grid-template-columns: 2fr;
5 row-gap: 2rem;
6 }
7 }

For example, the screen size for mobile devices (320px — 480px) will look like this:

Conclusion

The goal is to eliminate the need for excessive resizing, scrolling, zooming, or panning of images that arise on sites that are not mobile-friendly. With the Next.js Image component, images are responsive across as many devices.

Resources

You may find these resources helpful:

Emmanuel Ugwu

Software Engineering | Technical Writing | Web Development

I am a software engineer who is passionate about REST API's and building fast and scalable applications. I also write articles and other technical content to guide developers in the tech community.