Module P-13·22 min read

MDX with @next/mdx and custom component mapping, remote MDX from a CMS, the View Transitions API with the viewTransition config, and when MDX is the right choice vs a headless CMS.

JJS
Written by Jatin Jain Saraf · Senior Software Engineer

P-13 — MDX, View Transitions, and Content-Rich Application Patterns

Who this is for: Engineers building documentation sites, blogs, changelogs, or any application where content is a first-class concern — not just a few marketing pages, but a real content system. This module covers MDX from zero to production, the new View Transitions API in Next.js 15, and the architectural decisions that determine whether your content system scales or collapses under its own weight.


MDX vs a Headless CMS — Getting the Decision Right

MDX (Markdown with embedded JSX) and a headless CMS like Contentful, Sanity, or Notion are not competing solutions to the same problem. They solve different problems, and confusing them leads to regret.

MDX is the right choice when the people creating content are developers, the content lives in your repository, versioning alongside code is a feature rather than a burden, and the content sometimes needs to embed custom components or interactive elements that a CMS rich text editor can't express. Documentation sites (Next.js docs, Radix docs, Tailwind docs), changelogs, and developer-facing tutorials are natural MDX fits.

A headless CMS is the right choice when non-technical people need to author or edit content, when content needs to go through a review workflow, when content updates should be deployable without a code push, or when the same content is consumed by multiple surfaces (web, mobile, email). Marketing pages, blog posts authored by a content team, product descriptions, and landing pages belong here.

The failure mode is using MDX for content that non-developers will need to edit, or using a headless CMS for documentation that developers want to version-control. Both feel fine initially and become painful quickly. Make the choice based on who writes the content, not on what you find easier to implement.


Setting Up @next/mdx

The official @next/mdx package integrates MDX into the Next.js build pipeline. Install the dependencies and configure the plugin:

bash
ts

Adding 'md' and 'mdx' to pageExtensions means you can place .mdx files directly in your app/ directory and Next.js treats them as pages. An app/docs/getting-started.mdx file becomes the /docs/getting-started route. No routing boilerplate required.


mdx-components.tsx — Replacing HTML Elements

The mdx-components.tsx file at the root of your project (or src/) is how you map MDX's generated HTML elements to your own components. This is where the composition model of MDX really shines:

tsx

The h2 mapping above adds anchor links that appear on hover — the pattern you see in every good documentation site. The a mapping uses Next.js Link for internal URLs and a standard <a> with target="_blank" and rel="noopener noreferrer" for external ones. The img mapping replaces bare <img> tags with next/image for automatic optimization.


Frontmatter with gray-matter

MDX files often need metadata — title, description, date, author — that's separate from the rendered content. The frontmatter convention is YAML at the top of the file, delimited by ---:

mdx

Sign in to keep reading

The rest of this module is free — sign in with Google to unlock it and track your progress.

Sign in & Register

Discussion

0

Join the discussion

Loading comments...

© 2026 Jatin Jain Saraf (JJS). All rights reserved.