When I added a blog to this portfolio, I didn't just want plain Markdown — I wanted the same kind of rich content you see on engineering blogs: callout boxes, syntax-highlighted code, and properly optimized images.
tip
This entire post is rendered through the same MDX pipeline described below — it's real content, not a test fixture.
Rendering pipeline
Posts live in content/blog/*.mdx as frontmatter + Markdown/MDX body. lib/mdx.ts reads them with gray-matter, and app/blog/[slug]/page.tsx renders the body with next-mdx-remote/rsc's <MDXRemote>:
<MDXRemote
source={post.content}
components={mdxComponents}
options={{ mdxOptions: { rehypePlugins: [rehypeHighlight] } }}
/>
rehype-highlight adds hljs-prefixed classes to every fenced code block at build time, so syntax highlighting works with zero client-side JavaScript.
warning
Because posts are statically generated via generateStaticParams, adding a new post requires a rebuild — there's no live database behind this.
Custom components
Two custom components are registered in components/mdx/mdxComponents.tsx: a <Callout> component (used throughout this post) and an img override that swaps plain <img> tags for next/image, so Markdown images stay responsive and lazy-loaded automatically:

The result is a Markdown authoring experience with production-grade output — no manual image sizing, no unstyled code blocks, and reusable callouts for asides.