A rehype plugin for Contentlayer to copy body images to the public folder.
npm install rehype-cl-imgThis rehype plugin simply copies images from Contentlayer documents to the Nextjs public folder.
Say you have a folder full of .md or .mdx files. You wish to use images in the body of those
documents. Problem is, Contentlayer only supports images defined in the frontmatter. Images defined
in the body will be searched for in the public folder. But if you want to keep your images in the same
folder structure as your markdown files (say you have a git submodule for all of your content), that is
not an option.
This plugin solves that by finding all of the images defined in your markdown body and copying them over
to the public folder.
contentlayer.config.js include this:``ts`
export default makeSource({
mdx: {
rehypePlugins: [[rehypeClImg, {resourceDir: "/
}
});
In your Nextjs page, override the img tag with a custom component:
`ts
const mdxComponent: MDXComponents = {
img: ({src, alt, width, height}) =>
}
export default function Page() {
// ...
const MDXContent = useMDXComponent(post.body.code);
return (
rehypeClImg accepts the following options:publicDir?: string: is the name of your public directory. By default this is public.resourceDir: string: is the desired subdirectory within the public folder where the images will be copied to.excludeDir?: string: will be removed from the target directory path. For example, if you keep your images in an /images/
but don't want it to appear in the public directory (e.g. /public/*/images/), you can add it to excludeDir.$3
Say you have the following file structure
`
├── app
├── public
└── contentlayer-pages
└── documentation
└── foobar
├── images
│ └── foo.png
└── bar.mdx
`foo.png is referenced in bar.mdx as follows:`md
!some alt text
`With the following plugin settings:
`ts
rehypePlugins: [[rehypeClImg, {resourceDir: "docs", excludeDir: "images"}]]
`the plugin will copy foo.png to the public folder and preserve its folder structure:
`
├── app
├── public
│ └── docs // This comes from 'resourceDir' setting
│ └── documentation
│ └── foobar // 'images' subdirectory is ignored due to 'excludeDir' setting
│ └──foo.png
└── contentlayer-pages
└── documentation
└── foobar
├── images // this subdirectory is ignored
│ └── foo.png
└── bar.mdx`Finally, the compiled html will look like this:
`html

`The
src="/docs/documentation/foobar/foo.png" comes from the resourceDir` setting.