How to Build a Blogging Application Like Headbanger Blogs
This guide walks you through how to build a blogging platform similar to Headbanger Blogs:
- Content lives in Markdown/MDX files inside a
content/folder - Next.js (App Router) handles routing, rendering, and SEO
- A small
lib/blog.jsmodule reads files, parses frontmatter, and computesreading-time - The UI is built with React components and Tailwind CSS
You can follow this guide to either:
- Rebuild this project from scratch, or
- Understand how this repository works so you can customize it
1. Project Setup
1.1 Initialize a Next.js App Router project
Use the official Next.js starter:
Make sure you choose:
- App Router (recommended)
- TypeScript or JavaScript (this project uses JavaScript for most files)
- Tailwind CSS (or add it later)
1.2 Install required dependencies
This project relies on a few key packages:
gray-matter– parse frontmatter from Markdownreact-markdown– render Markdown as React componentsreading-time– estimate reading time from contentlucide-react– iconstailwindcss+ plugins – styling and typography
Install them:
If you didn't enable Tailwind in the Next.js wizard, also install and set it up following the Tailwind docs.
2. Content-First Architecture (Markdown + Folders)
Instead of storing posts in a database, this blog uses files on disk. This keeps things simple and works great for personal blogs and documentation sites.
2.1 Directory structure
At the root of the project, create a content/ folder. Each top-level folder inside content/ represents one main blog post / topic:
index.md– the main article for that topic
2.2 Frontmatter and body
Each index.md looks like this:
- The
---block is frontmatter – metadata used for the home page, cards, and SEO - The rest is standard Markdown, rendered by
react-markdownwith custom components
3. Reading and Transforming Content (lib/blog.js)
The file lib/blog.js is the heart of the content system. It handles file system operations to parse your Markdown files into structured data.
It:
- Reads directories inside
content/using Node'sfs - Parses each
index.md(andindex.mdx) withgray-matter - Computes
readTimeusingreading-time
Here is how getAllBlogPosts() is implemented:
This module also exports helpful navigation functions like getPreviousPost, getNextPost, and getSuggestedPosts, ensuring that creating related-post sections later in the UI is a breeze.
4. Routing and Pages (App Router)
This project uses the App Router (app/ directory) to define pages and server-side render the blog files.
4.1 Home page – list of all posts
File: app/page.js
- Calls
getAllBlogPosts()on the server. - Passes the result into a client component
HomeClientwhich handles search, filter by tag, and renders cards viacomponents/BlogCard.js. This keeps data loading on the server but interactivity on the client.
4.2 Dynamic route for main posts
File: app/blog/[slug]/page.js
Route: /blog/:slug
This server component is responsible for retrieving the post via its slug, formatting its data, and using next-mdx-remote/rsc to render the content alongside an immersive UI.
It beautifully couples the content generation with Next.js specific SSR mechanisms like generateStaticParams() to pre-render the paths.
5. Rendering Markdown Nicely (MDXComponents.js)
Markdown is rendered via react-markdown (or next-mdx-remote) and a custom MDXComponents map defined in components/MDXComponents.js.
This file is crucial for mapping standard markdown syntax (like # heading or ```code```) into visually striking, styled React components using Tailwind classes.
By keeping this separated, you achieve full control over the typography and look of the entire platform without muddying the markdown files.
6. Sidebar and Navigation Features
6.1 Table of contents sidebar
components/LeftSidebar.js (exported as PostSidebar) dynamically builds a list of headings by:
- Scanning the rendered document for
h1–h6tags - Generating IDs for headings if they don't exist
- Tracking which heading is currently visible using
IntersectionObserver - Rendering a clickable list that smoothly scrolls to each section
This gives you an automatic Table of Contents for long articles—no extra work in the content files.
6.2 Suggested posts navigation
components/RightSidebar.js (exported as PostNavigation) renders:
- The main article title and total reading time
- A "Suggested Posts" section with other relevant articles
These components turn a simple blog into a mini learning platform with structured navigation.
7. Styling with Tailwind CSS
The UI is built using Tailwind CSS classes:
- Layout:
flex,grid, responsive widths (w-full,md:w-[50vw], etc.) - Colors:
bg-background,text-muted-foreground, etc. - Typography: utility classes for headings, spacing, and text colors
To customize the look:
- Update the global styles in
app/globals.css - Adjust Tailwind config (colors, fonts, etc.)
- Tweak component classes in
components/for specific layouts
8. Adding a New Post (Your Workflow)
Once the system is set up, adding a new blog topic is simple:
-
Create a new folder inside
content/using a URL-friendly slug, e.g.: -
Add frontmatter and content to
index.md: -
Commit your changes and deploy – the new post automatically:
- Appears on the home page
- Gets its own
/blog/my-new-topicroute - Benefits from all navigation, sidebars, and styling
9. Deployment
You can deploy this app to any Next.js-compatible platform. Common options:
- Vercel – first-class support for Next.js, zero-config deployments
- Netlify – good support for static/SSR Next.js apps
- Self-hosted – Node server or Docker container
Typical workflow with Vercel:
- Push your project to GitHub
- Connect the repository in Vercel
- Vercel auto-detects Next.js and builds the app
- Every push to
maintriggers a new deployment
10. How to Customize This Blog for Your Own Use
Once you understand the structure, you can:
- Change the branding (logo, site name, colors)
- Add new layout components (e.g., a top navigation bar)
- Extend frontmatter with new fields (e.g.,
category,difficulty,series) - Integrate analytics or comments
- Swap file-based content for a headless CMS later, keeping the same rendering components
Because the content system and UI are decoupled, you can iterate on the design without touching the Markdown files—and vice versa.
11. Summary
To build a blogging app like this one, you mainly need to:
- Set up Next.js + Tailwind CSS
- Design a content-first structure in
content/withindex.md(orindex.mdx) - Write helper functions in
lib/blog.jsto read files and return structured data - Create dynamic routes under
app/blog/[slug] - Render Markdown with custom components via
react-markdown+MDXComponents - Enhance UX with navigation, sidebars, reading time, and suggested posts
This repository already includes all of these pieces—use this guide as a map to understand, extend, and build your own version of Headbanger Blogs.
