Skip to main content

How to Display Blog Post Count on Docusaurus Homepage

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

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 your blog/ 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

docusaurus blog posts counter

📚 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.