nextjs
engineering
meta

Building an SSR-Cached MDX Blog on Next.js 16

How this blog renders Markdown at build time, caches the article shell, and keeps views and comments live — all while running on Cloudflare.

June 10, 20261 min readviews

This blog is intentionally boring in the best way: posts are MDX files, the article HTML is cached and static, and only the small interactive bits — views, likes, comments — are dynamic.

The content layer

Every post lives in src/content/blog as an .mdx file with frontmatter. A build-time script reads each file and bakes its metadata into a manifest.

export const blogManifest = {
  "hello-world": {
    meta: { title: "Hello, World", date: "2026-06-07", tags: ["meta"] },
    load: () => import("@/content/blog/hello-world.mdx"),
  },
};

Why bake metadata at build time?

Because the site runs on Cloudflare Workers, where reading files from disk at request time is not available. Doing the work at build time keeps the runtime dependency-free.

Caching strategy

The article body is wrapped in the new "use cache" directive, so it becomes a fully static, CDN-cacheable shell. The mutable counters live in their own client components and fetch fresh numbers separately.

PieceCached?
Article bodyYes
View countNo
Like countNo
Comment listYes*

*The comment list is cached and revalidated whenever a new comment lands.

Engagement, but simple

Views and likes are deduplicated per visitor, and comments are anonymous with a lightweight spam check. No accounts, no friction.

Takeaway

Static where it can be, dynamic where it must be. That split keeps the blog fast and cheap to run.

Comments

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Loading comments…