Teachnique
      CourseRoadmaps
      Login

      Introduction

      Project SetupCLI

      IntroductionAPP RouterTemplateLoading UIError Handling404 Page

      Linking and Navigating

      Dynamic RoutesRoute groupsParallel RoutesIntercepting Routes

      Route handlersCacheCommon Questions

      Middleware

      CSRSSR & SSGISR

      React Server ComponentsServer-Side Rendering

      SuspenseStreaming

      Server & Client ComponentServer vs. Client ComponentBest Practices

      Server-Side Rendering Strategies

      Data Fetching & Caching & RedirectThird-Party Request Libraries on the Server SideBest Practices

      Request MemoizationData CacheFull Route CacheRouter Cache

      Server Actions IFormServer Actions IIOptimistic Update

      Tailwind CSSCSS-in-JSSass

      Environment VariablesAbsolute Imports& Module Path AliasesRoute Segment Config

      Image & LCPImage IImage IIOptimizing IOptimizing II

      Next FontFont ParameterApply Styles

      Feedback

      Submit request if you have any questions.

      Course
      Image I

      Next.js Mastery: From Fundamentals to Full-Stack

      Unlock the power of Next.js with this comprehensive course! Starting with the basics, you’ll learn essential skills such as routing, data fetching, and styling. Progress through practical projects, including building your own React Notes app, to gain hands-on experience. Dive into the source code to understand the inner workings and core principles of Next.js. Perfect for developers with a basic knowledge of React and Node.js, this course ensures you’ll be ready to create high-performance full-stack applications efficiently. Join us and master Next.js, backed by industry experts and a supportive learning community.

      Image

      1. Feature Highlights

      Explaining LCP (Largest Contentful Paint) is just to help everyone understand the importance of image optimization (since the largest content element is often an image). Moving on to the <Image> component, Next.js builds on the native HTML <img> element to implement these optimization features:
      • Size Optimization: Automatically provides the correct size image for each device and uses modern image formats like WebP and AVIF.
      • Visual Stability: Prevents layout shifts during image loading.
      • Faster Page Load: Images only load when they enter the viewport, using lazy loading with an optional blur placeholder.
      • Flexible Configuration: Allows on-demand image adjustments, including support for images from remote servers.
      
      We'll cover these features one by one when explaining the component API.

      2. Basic Usage

      Here’s an example of using the <Image> component. It looks just like using a normal <img> element:
      // app/page.js
      import Image from 'next/image'
      
      export default function Page() {
      return (
      <Image
      src="/profile.png"
      width={500}
      height={500}
      alt="Picture of the author"
      />
      )
      }

      3. Supported Props

      The <Image> component supports these props:
      Prop
      Example
      Type
      Required
      src
      src="/profile.png"
      String
      Yes
      width
      width={500}
      Integer (px)
      Yes
      height
      height={500}
      Integer (px)
      Yes
      alt
      alt="Picture of the author"
      String
      Yes
      loader
      loader={imageLoader}
      Function
      No
      fill
      fill={true}
      Boolean
      No
      sizes
      sizes="(max-width: 768px) 100vw"
      String
      No
      quality
      quality={80}
      Integer (1-100)
      No
      priority
      priority={true}
      Boolean
      No
      placeholder
      placeholder="blur"
      String
      No
      style
      style={{objectFit: "contain"}}
      Object
      No
      onLoadingComplete
      onLoadingComplete={img => done()}
      Function
      No
      onLoad
      onLoad={event => done()}
      Function
      No
      onError
      onError={event => fail()}
      Function
      No
      loading
      loading="lazy"
      String
      No
      blurDataURL
      blurDataURL="data/jpeg..."
      String
      No
      Among these, src, width, height, and alt are required. Let's go through them one by one.

      4. src - Required

      The src prop supports passing in a static image file or a string path.
      When using a local image, you can statically import the image file. Import files in .jpg, .png, or .webp formats using import. Here’s an example:
      // app/page.js
      import Image from 'next/image'
      import profilePic from './me.png'
      
      export default function Page() {
      return (
      <Image
      src={profilePic}
      alt="Picture of the author"
      // width={500} automatically provided
      // height={500} automatically provided
      // blurDataURL="data:..." automatically provided
      // placeholder="blur" // Optional blur-up while loading
      />
      )
      }
      When using static file import, width and height are not required, as Next.js will automatically provide them.
      Note: Dynamic await import() or require() is not supported. The import must be static for analysis during the build. When using remote images, src can accept a URL string.
      Since Next.js cannot fetch remote files during the build, you need to manually provide the width, height, and optionally, the blurDataURL props.
      The width and height attributes help infer the correct aspect ratio and avoid layout shifts during image loading. However, width and height do not determine the final rendered size, which makes sense since you might set stretching modes, etc.
      // app/page.js
      import Image from 'next/image'
      
      export default function Page() {
      return (
      <Image
      src="https://s3.amazonaws.com/my-bucket/profile.png"
      alt="Picture of the author"
      width={500}
      height={500}
      />
      )
      }
      When using remote URLs, Next.js requires defining supported remote image URLs in the next.config.js file to prevent malicious usage. Here's how to configure it:
      // next.config.js
      module.exports = {
      images: {
      remotePatterns: [
      {
      protocol: 'https',
      hostname: 's3.amazonaws.com',
      port: '',
      pathname: '/my-bucket/**',
      },
      ],
      },
      }
      We'll explain remotePatterns in detail later in this article.

      5. width - Required

      The width attribute indicates the rendered width of the image in pixels, affecting its display size.
      This attribute is required unless the image is statically imported or has the fill attribute.

      6. height - Required

      The height attribute indicates the rendered height of the image in pixels, affecting its display size.
      This attribute is required unless the image is statically imported or has the fill attribute.

      7. alt

      The alt attribute is used to describe the image, providing information to screen readers and search engines. If the image is disabled or an error occurs during loading, it serves as fallback text.
      The alt attribute should provide a text description that replaces the image without changing the meaning of the page. It should not repeat information provided in captions above or below the image.
      If the image is purely decorative or not intended for user interaction, the alt attribute should be an empty string (alt="").

      8. loader

      The loader prop represents a custom function for resolving image URLs. Let’s look at an example:
      'use client'
      
      import Image from 'next/image'
      
      const imageLoader = ({ src, width, quality }) => {
      return `https://example.com/${src}?w=${width}&q=${quality || 75}`
      }
      
      export default function Page() {
      return (
      <Image
      loader={imageLoader}
      src="me.png"
      alt="Picture of the author"
      width={500}
      height={500}
      />
      )
      }
      The function takes src, width, and quality as parameters and returns the image URL string.
      Note: Since the loader prop is passed a function, you need to use a client component. In this example, the top line uses 'use client'.
      Adding a loader to every image can be cumbersome, so you can configure the loaderFile option in next.config.js to apply to every next/image instance without needing to pass the loader prop. We’ll explain this configuration option later in the article.

      9. fill

      fill={true} // {true} | {false}
      The fill prop indicates whether the image should fill its parent element. The default value is false. This is useful when the image’s width and height are unknown.
      However, note that when using fill, the parent element must be set to position: "relative", position: "fixed", or position: "absolute". The <img> element will automatically be set to position: "absolute" by default.
      If no other styles are applied, the image will be stretched to fill the container.
      There are many ways to fill a container. The CSS property object-fit: "contain" or object-fit: "cover" can also be used to fill the image.
      Let’s look at a simple example:
      // app/page.js
      import Image from 'next/image'
      import profilePic from './image.png'
      
      export default function Page() {
      return (
      <div style={{
      width: '200px',
      height: '200px',
      backgroundColor: "#ccc",
      position: 'relative'
      }}>
      <Image
      src={profilePic}
      alt="Picture of the author"
      />
      </div>
      )
      }
      The normal display looks like this:
      
      If the fill prop is added:
      <Image
      src={profilePic}
      alt="Picture of the author"
      fill={true}
      />
      The result will look like this, with the image stretched to fit the container:
      
      If you use object-fit: "contain":
      <Image
      src={profilePic}
      alt="Picture of the author"
      fill={true}
      style={{objectFit: "contain"}}
      />
      The result will be as follows, with the image filling the entire content box while maintaining its aspect ratio:
      
      If you use object-fit: "cover":
      <Image
      src={profilePic}
      alt="Picture of the author"
      fill={true}
      style={{objectFit: "cover"}}
      />
      The result will be as follows, with the image filling the entire content box while maintaining its aspect ratio. If the aspect ratio of the object does not match the content box, the object will be cropped to fit the content box:
      

      10. sizes

      HTML 5.1 introduced the srcset and sizes attributes for the <img> element to set responsive images.
      When we need to display different images on different devices, we use srcset. There are two specific scenarios: the image has the same dimensions but different resolutions for different images, i.e., higher resolution images for higher pixel densities; or the same image content is displayed larger or smaller based on the device. These correspond to the two syntaxes of srcset.
      First, let’s discuss the first scenario, where different images are displayed based on different resolutions. Here’s an example:
      <img
      srcset="elva-fairy-320w.jpg, elva-fairy-480w.jpg 1.5x, elva-fairy-640w.jpg 2x"
      src="elva-fairy-640w.jpg"
      alt="Elva dressed as a fairy" />
      The result looks like this:
      
      srcset is a comma-separated list of one or more strings, each composed of:
      • A URL pointing to the image
      • A space (optional)
      • A pixel density descriptor (a positive floating-point number followed by the x symbol)
      If we apply a CSS style to the image:
      img {
      width: 320px;
      }
      Its width on the screen will be 320 pixels (CSS pixels). The browser calculates the resolution of the display and displays the most appropriate image from the srcset. If it’s a normal resolution, where one device pixel equals one CSS pixel, it loads elva-fairy-320w.jpg, which is 39KB. If the device has a high pixel density, where two or more device pixels equal one CSS pixel, it loads elva-fairy-640w.jpg, which is 93KB.
      Now, let’s discuss the second scenario, where the same image content is displayed larger or smaller based on the device. Here’s an example:
      <img
      srcset="elva-fairy-small.jpg 480w, elva-fairy-large.jpg 800w"
      src="elva-fairy-large.jpg"
      alt="Elva dressed as a fairy"
      />
      The syntax of srcset is slightly different from the previous example. It defines a set of images that the browser can choose from, along with the size of each image. Analyzing the syntax, it is still a comma-separated list of one or more strings, each composed of:
      • A URL pointing to the image
      • A space
      • The intrinsic width of the image (in pixels). Note that here we use the width descriptor w, not px. But 1 w corresponds to 1 pixel. The intrinsic width of the image refers to its actual size.
      This tells the browser that two alternative images are available for display, one is elva-fairy-small.jpg with a width of 480px, and the other is elva-fairy-large.jpg with a width of 800px.
      How does the browser know which image to use? For example, if the device viewport width is 640px, should it choose the 480px image or the 800px image?
      To help the browser decide, you need to use the sizes attribute. The sizes attribute is a set of media query conditions that tell the browser which image to use under what conditions. Here’s an example:
      <img
      srcset="elva-fairy-small.jpg 480w, elva-fairy-large.jpg 800w"
      sizes="(max-width: 600px) 480px,
      800px"
      src="elva-fairy-large.jpg"
      alt="Elva dressed as a fairy"
      />
      sizes is a comma-separated list of one or more strings, each composed of:
      • A media condition, in this example (max-width:600px), which means when the viewport width is less than or equal to 600px.
      • A space
      • The slot size the image will fill when the media condition is true. This width can be a fixed value, like 480px in this example, or a relative width to the viewport (like 50vw), but it cannot be a percentage. If there is no media condition, it applies by default. Once the browser matches the first media condition, all remaining conditions are ignored, so order matters.
      With these attributes, the browser will:
      • Check the device width.
      • Check which media condition in the sizes list is true first.
      • Determine the slot size given by that media query.
      • Load the image from the srcset list that most closely matches the selected slot size.
      For example, in this case, if the browser’s viewport is 480px, the first condition (max-width: 600px) in sizes is true, so it selects the 480px size, and since 480px matches the 480w intrinsic width in srcset, it loads elva-fairy-small.jpg. This way, smaller images load on mobile devices, speeding up load times.
      After explaining the srcset and sizes attributes for the <img> element, let’s return to the <Image> component. With Next.js, you don’t need to set srcset as it will be generated automatically for you. Setting the sizes attribute affects the generated srcset values.
      If you don’t set the sizes attribute in the component, Next.js will use pixel density descriptors like 1x, 2x. But if you set the sizes attribute, Next.js will use intrinsic width descriptors like 640w, 750w.
      Before Setting:
      
      After Setting: