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.