Published on

Images in Next.js

Authors

    Introduction

    The tailwind starter blog has out of the box support for Next.js's built-in image component and automatically swaps out default image tags in markdown or mdx documents to use the Image component provided.

    Usage

    To use in a new page route / javascript file, simply import the image component and call it e.g.

    import Image from 'next/image'
    
    function Home() {
      return (
        <>
          <h1>My Homepage</h1>
          <Image src="/me.png" alt="Picture of the author" width={500} height={500} />
          <p>Welcome to my homepage!</p>
        </>
      )
    }
    
    export default Home
    

    For a markdown file, the default image tag can be used and the default img tag gets replaced by the Image component in the build process.

    Assuming we have a file called ocean.jpg in data/img/ocean.jpg, the following line of code would generate the optimized image.

    ![ocean](/static/images/sql-practice-question/PlayerTable1.png)
    

    Alternatively, since we are using mdx, we can just use the image component directly! Note, that you would have to provide a fixed width and height. The img tag method parses the dimension automatically.

    <Image alt="ocean" src="/static/images/ocean.jpg" width={256} height={128} />
    

    Note: If you try to save the image, it is in webp format, if your browser supports it!

    ocean

    Photo by YUCAR FotoGrafik on Unsplash

    Benefits

    • Smaller image size with Webp (~30% smaller than jpeg)
    • Responsive images - the correct image size is served based on the user's viewport
    • Lazy loading - images load as they are scrolled to the viewport
    • Avoids Cumulative Layout Shift
    • Optimization on demand instead of build-time - no increase in build time!

    Limitations

    • Due to the reliance on next/image, unless you are using an external image CDN like Cloudinary or Imgix, it is practically required to use Vercel for hosting. This is because the component acts like a serverless function that calls a highly optimized image CDN.

      If you do not want to be tied to Vercel, you can remove imgToJsx in remarkPlugins in lib/mdx.js. This would avoid substituting the default img tag.

      Alternatively, one could wait for image optimization at build time to be supported. A different library, next-optimized-images does that, although it requires transforming the images through webpack which is not done here.

    • Images from external links are not passed through next/image

    • All images have to be stored in the public folder e.g /static/images/ocean.jpeg