While migrating my blog from Hugo to Next.js, I encountered a problem. In Hugo, I could easily keep the images in the same folder as the markdown file, but Next.js did not offer this feature. Relocating all the images manually seemed like a tedious task, so I devised a plan to automate it during the build process.
Step 1: Gathering Images at Build Time
To begin, I needed to create a folder within /public/images
for each blog post and move the corresponding images into them. To achieve this, I created a postbuild.mjs
file with the following code snippet:
import fs from 'fs'
import path from 'path'
import fsExtra from 'fs-extra'
const source = './content/posts'
const destination = './public/images'
const posts = fs.readdirSync(source)
fsExtra.emptyDirSync(destination)
fs.mkdir(destination, () => {
posts.map((slug) => {
if (slug === '.DS_Store') return
fs.mkdir(`${destination}/${slug}`, () => {
fs.readdirSync(`${source}/${slug}`)
.filter((item) =>
['.png', '.jpg', '.jpeg', '.gif'].includes(path.extname(item))
)
.map((item) => {
fs.copyFile(
`${source}/${slug}/${item}`,
`${destination}/${slug}/${item.replace(/ /g, '-')}`,
() => {
console.log(`${destination}/${slug}/${item}`)
}
)
})
})
})
})
This code reads each blog post directory, filters out the image files, creates the corresponding folder in /public/images
, and copies the images into their respective folders.
Step 2: Updating the Package.json File
To ensure the postbuild.mjs
script is executed after the Next.js build process, include the following postbuild
entry in your package.json
file’s scripts
section:
{
...
"scripts": {
"build": "next build",
"postbuild": "node ./postbuild.mjs",
"dev": "next dev",
"start": "next start",
...
}
}
You can also create a prebuild
entry that runs before the build process, using the same technique. Note that this feature is not unique to Next.js; it is a broader npm feature. Refer to the npm documentation for more information.
By following these steps, you can efficiently manage your images and streamline your workflow when using Next.js.