Building a Static Blog with MDX and Next.js

A technical walkthrough of the zero-runtime blog architecture powering this site — MDX files, static generation, and a Git-based publish flow.

2 min read
engineeringnext.jsmdxvercel

Building a Static Blog with MDX and Next.js

Most blog setups fall into two camps: heavy CMS platforms or bare-bones markdown renderers. This site sits in the sweet spot — full MDX component support, syntax highlighting, and zero runtime cost.

Design Constraints

  1. No database — content lives in Git, versioned alongside code.
  2. No API routes — everything resolves at build time.
  3. Full MDX — I can drop React components into prose when I need interactive demos.
  4. Syntax highlighting — powered by Shiki via rehype-pretty-code, themed to match the site.

The Pipeline

content/blog/*.mdx
       ↓
  gray-matter (front-matter)
       ↓
  MDXRemote (remark-gfm, rehype-slug, rehype-pretty-code)
       ↓
  Static HTML at /blog/[slug]

Front-matter Schema

Every post declares metadata in YAML front-matter:

---
title: "Post Title"
description: "One-liner for meta tags and cards"
date: "2025-06-25"
tags: ["tag-a", "tag-b"]
published: true
---

The published flag defaults to true; set it to false to keep a draft in the repo without it appearing on the site.

Static Generation

generateStaticParams reads the content/blog/ directory at build time and returns every slug, so Vercel pre-renders each page to static HTML:

export async function generateStaticParams() {
  return getAllSlugs().map((slug) => ({ slug }));
}

No ISR, no revalidation — a new deploy is the cache-bust.

Publishing from Mobile

The end goal is an iOS app that:

  1. Drafts a post in a local editor with Markdown preview.
  2. Commits the .mdx file to the repo via the GitHub Contents API.
  3. Vercel detects the push and rebuilds automatically.

All of this happens without a backend — the "server" is GitHub + Vercel's build pipeline.

What I'd Add Next

  • Tag filtering — client-side filter on the blog index.
  • Reading time — computed from word count at build time.
  • OG images — auto-generated via @vercel/og using post metadata.

That's the architecture. Simple, fast, and entirely in Git.

Rishi Saha.

HUD · Page · Tree