Skip to main content

How to Display Blog Post Count on Docusaurus Homepage

Β· 4 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 blogStats.js:

// scripts/blogStats.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, 'blogStats.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/blogStats.js",
"start": "docusaurus start",
"dev": "docusaurus start",
...
}
}

Now, every time you run npm run build, the script will generate src/data/blogStats.json before Docusaurus builds the site.

3. Create a Reusable Component​

Create src/components/BlogPostCount.js:

import React from 'react';
import blogStats from '../data/blogStats.json';

export default function BlogPostCount() {
return (
<p className="padding-horiz--md">
πŸ“š Total Blog Posts: <strong>{blogStats.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.