How to Display Blog Post Count on Docusaurus Homepage
Many developers using Docusaurus want to display the number of blog posts they have—especially on their homepage. While this may sound trivial, doing it the right way (that works on both your local dev and production builds like Vercel) requires some thought.
Here’s a simple and reliable way to implement this—no hacks, no unstable APIs, just clean engineering.
💡 Problem
You can’t just use internal hooks like useBlogPosts()
inside your homepage (src/pages/index.js
), because Docusaurus statically renders this file during build. And those hooks aren’t available at build time, which will cause your build to fail—especially on platforms like Vercel.
✅ Solution: Use a Build-Time Script
We’ll write a small Node.js script that:
- Counts all
.md
and.mdx
files inside yourblog/
folder - Writes that number into a JSON file
- Imports that JSON at build-time to show the count
🧱 Step-by-Step Guide
1. Create a Script
In your project root, create a new directory: mkdir scripts
Inside it, create blogCount.js
:
// scripts/blogCount.js
const fs = require('fs');
const path = require('path');
const blogDir = path.join(__dirname, '..', 'blog');
function getMarkdownFiles(dir) {
if (!fs.existsSync(dir)) return [];
return fs
.readdirSync(dir)
.filter(file => file.endsWith('.md') || file.endsWith('.mdx'));
}
const count = getMarkdownFiles(blogDir).length;
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: ${count}`);
2. Open package.json and update the scripts block
{
"scripts": {
"build": "npm run count:blogs && docusaurus build",
"count:blogs": "node scripts/blogCount.js",
"start": "docusaurus start",
"dev": "docusaurus start",
...
}
}
Now, every time you run npm run build, the script will generate src/data/blogCount.json before Docusaurus builds the site.
3. Create a Reusable Component
Create src/components/BlogPostCount.js:
import React from 'react';
import blogCount from '../data/blogCount.json';
export default function BlogPostCount() {
return (
<p className="padding-horiz--md">
📚 Total Blog Posts: <strong>{blogCount.count}</strong>
</p>
);
}
4. Use It in Your Homepage
Open src/pages/index.js (or src/pages/index.tsx) and use the component:
import React from 'react';
import Layout from '@theme/Layout';
import BlogPostCount from '../components/BlogPostCount';
export default function Home() {
return (
<Layout title="Welcome">
<main className="margin-vert--xl">
<h1>Hello 👋</h1>
<BlogPostCount />
</main>
</Layout>
);
}
Now when you build and deploy your site, the count will be visible on the homepage and updated automatically.
🚀 Production-Ready
This solution:
- Works with Server-Side Rendering (SSR)
- Works with Vercel, Netlify, or static file hosting
- Avoids unstable internal Docusaurus APIs
- Can be extended to collect other data (e.g., blog titles, tags)
✅ Example Output
📚 Total Blog Posts: 14
👋 Final Thoughts
This is a small detail, but it’s these kinds of touches that make your static site feel alive and professional. As your content grows, your site keeps up—automatically.