When managing images in a Hexo blog, most setups usually fall into one of two patterns:

  1. Create a folder with the same name as the post inside _post
  2. Put everything into a shared images folder under source

Both approaches work, but both have trade-offs. Keeping images next to each post makes them easy to locate, yet it also clutters the post directory. A single centralized images folder keeps resources together, but finding and maintaining assets over time becomes more tedious.

A practical middle ground is to create a subfolder for each post inside images. In other words, store images under source/images/<post-name>/.

This keeps the convenience of per-post organization while preserving the centralized structure of a single image directory.

How to set it up

Create a JavaScript file inside the scripts directory at the root of your Hexo project. If that directory does not exist yet, create it first. The file can be named auto-image-folder.js.

const fs = require("fs")
const path = require("path")

hexo.on("new", function(data) {
        const postName = path.basename(data.path, ".md")
        const imageDir = path.join(hexo.source_dir, "images", postName)

        if(!fs.existsSync(imageDir)){
                fs.mkdirSync(imageDir, {recusive: true})
        }
})

With this script in place, every time you create a new post, Hexo will also create a matching folder inside images.

Quick test

Run:

hexo new "新文章"

After that, a folder with the same name as the post will appear under the images directory.

Editor workflow: Typora

To make image handling smoother while writing, Typora can be configured to place pasted or inserted images directly into the post-specific folder.

Open Typora → Preferences → Image and use these settings:

  • When Insert Local Images: Copy to specified path
  • Custom Path: ../source/images/${filename}/
  • Enable Prefer relative path

A resulting directory can look like this:

PS E:\blog> ls .\source\images\测试\


    目录: E:\blog\source\images\测试


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         2025/6/29     11:14            229 image-20250629111411456.png

Once this is set, creating posts and managing their images becomes much more straightforward.