← Writing

How this site handles content

The MDX pipeline behind these posts: file discovery, metadata exports, and static generation.

1 min read
next.jsmdx

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.

FieldRequiredNotes
titlenoFalls back to the slug
descriptionnoUsed for <meta name="description">
datenoYYYY-MM-DD, drives sort order
tagsnoRendered under the post title
draftnoHidden 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.