Optimizing images with the Next.js Image component

Versions used:
  • react@17.0.1
  • next@10.0.1

This article has been updated for next@10.0.1.

The release of Next.js 10.0.0 introduces the long awaited Image component. Optimizing images in Next.js now works completely out of the box and requires minimal effort to implement.

Getting started

Using the Image component is very straightforward, as the properties are compatible with the native img tag. If you want to update images in your Next.js app to make use of optimization, we can simply replace our existing img tag with the new Image component and leave the same properties.

// pages/index.js

import Image from 'next/image';

const Page = () => {
  return (
    <Image
      src="/image.png"
      width="100"
      height="100"
    />
  );
};

export default Page;

Responsive images

Don't worry about handling responsive images with the width and height properties, Next.js's Image component is responsive by default. Setting the size on the Image component helps Next.js determine the initial size of it's internal responsive container.

We can change the responsive behaviour of the Image component by providing a layout property. The default layout is set to "intrinsic", which will resize the images down if the viewport is smaller than the defined image dimensions. Passing the "responsive" value for the layout prop will both scale the image up and down depending on the viewport.

If you don't want to set the image dimensions, you can use the fill behaviour using the layout prop. The Image component will now automatically resize to the dimensions of its container.

You can disable the responsive behaviour on the Image component by providing a "fixed" value on it's layout prop.

Next.js will automatically generate a set of images optimized for different screen sizes. Instead of having one huge hero background image served to every device, the Image component will load the resized version based on the visitors screen size.

Customizing loading strategies

By default the Image component will use lazy loading. This means that the image will only be loaded once the viewport reaches a certain calculated distance from the image. You can change the loading prop to "eager", to make sure the image loads immediately.

You can prioritize specific images to load when they're considered high priority by passing a true to the priority prop. Use priority sparingly and only on images that are above the fold. The default loading and priority strategies suit most implementations.

Using the Image component with external images

The Image component works out of the box with external images. If you're hosting images on a different domain than your Next.js application, you'll have to configure Next.js to handle these.

// next.config.js
module.exports = {
  images: {
    domains: [
      'example.com',
      // If you're using subdomains you need
      // to configure the full host name
      // 'cdn.example.com',
    ],
  },
};

Updating the Image component

After configuring our Next.js app we can start using the Image component with the external domains.

// pages/index.js

import Image from 'next/image';

const IndexPage = () => {
  return (
    <Image
      src="http://example.com/image.png"
      width="100"
      height="100"
    />
  );
};

export default IndexPage;

Customizing image quality and generated sizes

You can update the quality of the generated images by passing a quality prop on the Image component with a value between 1 to 100.

By passing an array of integers into the sizes prop, you can override the breakpoints on which Next.js generates images.

If you want to change the default breakpoints which Next.js uses for all images, you can add add a deviceSizes array inside your images key of the next.config.js.

// pages/index.js

import Image from 'next/image';

const IndexPage = () => {
  return (
    <Image
      src="http://example.com/image.png"
      width="100"
      height="100"
      quality={100}
      sizes={[320, 520]}
    />
  );
};

export default IndexPage;

The new Image component simplifies handling image optimization for images with both a relative and an absolute path. Thanks to Next.js' sane defaults, it's easy to convert your current img tags to the new Image component.

To get the best use out of the new Image component, make sure you read the docs about Image Component and Image Optimization over at the Next.js website.

Stephan Lagerwaard
Stephan Lagerwaard
Frontend Engineer at Fiberplane.