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.
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.
| Piece | Cached? |
|---|---|
| Article body | Yes |
| View count | No |
| Like count | No |
| Comment list | Yes* |
*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
Loading comments…