Skip to main content

Improved: Count Blog Posts in Docusaurus Including Folders

Β· 3 min read
Serhii Hrekov
software engineer, creator, artist, programmer, projects founder

πŸ”„ Update to: Count Number of Blog Posts in Docusaurus and Vercel

In my previous post, I shared a method to count the number of blog posts in a Docusaurus project and display it on your homepage, fully compatible with Vercel and static builds.

That method works greatβ€”if all your blog posts are plain .md or .mdx files in the blog/ directory.

But if you're like me and prefer organizing blog posts in folders (e.g., blog/my-post/index.md), the previous approach silently misses those.

Let’s fix that.


πŸ› οΈ The Problem​

The old script only counted individual .md or .mdx files in blog/. It ignored directories that contained markdown-based blog posts like:

blog/
β”œβ”€β”€ my-article.md
β”œβ”€β”€ cool-folder-post/
β”‚ └── index.mdx

In this example, only my-article.md would be counted. Not ideal.


βœ… The Fix: Count Files and Folders with Markdown​

Here’s the updated scripts/blogCount.js file that:

  • Counts .md / .mdx files directly
  • Also counts directories that contain a .md or .mdx file
const fs = require('fs');
const path = require('path');

const blogDir = path.join(__dirname, '..', 'blog');

function countBlogEntries(dir) {
if (!fs.existsSync(dir)) return 0;

let count = 0;

const entries = fs.readdirSync(dir, { withFileTypes: true });

for (const entry of entries) {
const fullPath = path.join(dir, entry.name);

if (entry.isFile() && (entry.name.endsWith('.md') || entry.name.endsWith('.mdx'))) {
count += 1;
} else if (entry.isDirectory()) {
const innerFiles = fs.readdirSync(fullPath);
const hasMarkdown = innerFiles.some(f => f.endsWith('.md') || f.endsWith('.mdx'));
if (hasMarkdown) {
count += 1;
}
}
}

return count;
}

const count = countBlogEntries(blogDir);

const outputPath = path.join(__dirname, '..', 'src', 'data');
if (!fs.existsSync(outputPath)) {
fs.mkdirSync(outputPath, { recursive: true });
}

fs.writeFileSync(
path.join(outputPath, 'blogCount.json'),
JSON.stringify({ count }, null, 2)
);

console.log(`βœ… Blog post count (files + folders): ${count}`);

πŸ§ͺ Example​

This structure:

blog/
β”œβ”€β”€ 01-simple.md
β”œβ”€β”€ 02-folder-post/
β”‚ └── index.md
β”œβ”€β”€ 03-another-folder/
β”‚ └── something.mdx

Will now correctly return:

βœ… Blog post count (files + folders): 3

πŸ“¦ How It Fits In​

This script is still executed at build time, before Docusaurus generates your static site. Your package.json stays the same:

"scripts": {
"build": "npm run count:blogs && docusaurus build",
"count:blogs": "node scripts/blogCount.js"
}

And you can still read the blogCount.json file in your homepage like this:

import blogCount from '../data/blogCount.json';

export default function BlogPostCount() {
return <p>πŸ“š Total Blog Posts: <strong>{blogCount.count}</strong></p>;
}

πŸš€ Final Notes​

If your blog post structure mixes flat files and folders (which Docusaurus fully supports), this update makes sure your count reflects the actual number of published articles.

You can now confidently display the total number of posts β€” no matter how you organize your content.