Using NextJS Image Component with MDX

11/21/2021

The NextJS provides a great image component that supports optimizing the image size based on the display size of the device, but just relying on the documentation alone can be frustrating. You might be stumped on how to get the height and width of the image while using the component.

This post will help you correctly use the image component so that you can benefit from the optimization it offers.

Getting the dimensions of the image

We will be using rehype-img-size plugin to fetch the image size of each image in all the markdown/MDX files. But before we can use this plugin, we need to create a custom image component that uses the NextJS image component, so that we could easily replace the component in the future if the need arise, and to set the layout prop as responsive for the NextJS component.

import NextImage from "next/image"

const Image = ({ src, alt, height, width }) => {
  const imageProps = {
    src,
    alt,
    height,
    width,
    layout: "responsive"
  }
  return <NextImage {...imageProps} />
}

export default Image

In your MDXRemote provided by next-mdx-remote, we need to pass this image component in the components prop, for it to be used while the markdown is rendered.

const components = {
  img: Image
}

const MDX = ({ mdxSource }) => {
  return (
    <div>
      <MDXRemote {...mdxSource} components={components} />
    </div>
  )
}

For additional preprocessing while preparing the mdxSource, we define the rehype-img-size plugin in the rehypePlugins with the directory where the images are stored. This is needed as the plugin only supports images stored in the relative path.

import rehypeImgSize from "rehype-img-size"

export const getStaticProps: GetStaticProps<
  PageProps,
  Params
> = async context => {
  // omitted for brevity
  const mdxSource = await serialize(content, {
    mdxOptions: {
      rehypePlugins: [[rehypeImgSize, { dir: "public" }]]
    }
  })
  // omitted for brevity
}

Closing Thoughts

Although the rehype-img-size plugin (as of v0.0.1) only supports local images, we could easily add support for external images by fetching the images to a specific directory and then using image-size plugin on the downloaded images or use a different plugin that supports both.

References

© 2025 Joel Jacob