How this site handles content
The MDX pipeline behind these posts: file discovery, metadata exports, and static generation.
Posts here are plain .mdx files. There's no CMS, no database, and no build
step beyond next build. This post is the documentation for that setup.
Where posts live
Every file in content/ ending in .mdx becomes a post. The filename is the
URL slug, so content/hello-world.mdx is served at /blog/hello-world.
Metadata
@next/mdx doesn't parse YAML frontmatter. Instead, each post exports a
metadata object, which is just a normal JavaScript export that the rest of
the app can import:
export const metadata = {
title: "Hello world",
description: "Why this blog exists.",
date: "2026-09-05",
tags: ["meta"],
};
Post body starts here.
lib/posts.ts reads the directory, imports each module, and normalizes those
exports into a typed Post. Missing fields get sensible defaults rather than
crashing the build.
| Field | Required | Notes |
|---|---|---|
title | no | Falls back to the slug |
description | no | Used for <meta name="description"> |
date | no | YYYY-MM-DD, drives sort order |
tags | no | Rendered under the post title |
draft | no | Hidden in production builds |
Drafts
Setting draft: true keeps a post visible during next dev and excludes it
from production entirely — it isn't listed, and generateStaticParams never
emits a route for it, so there's no unlisted URL to stumble onto.
Static generation
The [slug] route enumerates posts at build time and sets dynamicParams to
false:
export const dynamicParams = false;
export async function generateStaticParams() {
const posts = await getAllPosts();
return posts.map((post) => ({ slug: post.slug }));
}
Every post is prerendered to static HTML, and anything outside that set 404s instead of being rendered on demand.
Components in posts
Because it's MDX, a post can import and render React components inline. Global
overrides live in mdx-components.tsx — that's where internal links become
next/link and images get routed through next/image when they carry
dimensions.