Next.js as a CMS: Using MDX and Git-Based Content for Developer Websites | SoniNow Blog

Limited TimeLearn More

next.jsmdxcmsgit-based cmsweb development

Next.js as a CMS: Using MDX and Git-Based Content for Developer Websites

Published

2026-06-23

Read Time

5 mins

Next.js as a CMS: Using MDX and Git-Based Content for Developer Websites

For developer-focused websites, documentation portals, and marketing sites where the development team owns the content, a traditional CMS often feels like overhead. Enter the Git-based CMS approach: content written as Markdown or MDX files, stored in the same repository as the code, and rendered by Next.js at build or request time. This workflow eliminates database management, API rate limits, and the sync drift between content and code that plagues traditional CMS architectures.

Why Choose MDX Over a Traditional CMS

MDX is a superset of Markdown that allows you to import and use React components directly within your content files. This means you can embed interactive charts, code playgrounds, video components, and custom callout boxes without any CMS plugin or shortcode system. For developer documentation, MDX enables live code examples, prop tables generated from TypeScript types, and interactive API explorers — all authored in plain text files.

The Git-based approach also inherits all the benefits of version control: pull requests for content changes, branch-based previews, content review workflows, and the ability to roll back any change instantly. There is no "database restore" scenario — git revert is your undo button.

Setting Up Next.js with MDX

The @next/mdx package configures Next.js to process .mdx files placed in the contents/ or pages/ directory. Start by installing the dependencies:

npm install @next/mdx @mdx-js/loader @mdx-js/react

Configure your next.config.mjs to enable MDX processing:

import createMDX from '@next/mdx';
const withMDX = createMDX({ extension: /\.mdx?$/ });
export default withMDX({ pageExtensions: ['tsx', 'md', 'mdx'] });

Now any .mdx file in the pages/ directory becomes a route automatically. For blog posts and documentation that live outside the pages directory, use next-mdx-remote to parse and render MDX at runtime from files fetched via the filesystem.

Content Modeling with Frontmatter

Each MDX file includes YAML frontmatter for metadata — title, description, tags, publication date, author, and SEO fields. Use the gray-matter library to parse frontmatter and pass it as props to your page components:

import matter from 'gray-matter';
import fs from 'fs';
import path from 'path';

export function getPost(slug) {
  const filePath = path.join(process.cwd(), 'contents', `${slug}.mdx`);
  const source = fs.readFileSync(filePath, 'utf8');
  const { data, content } = matter(source);
  return { frontmatter: data, content };
}

For more structured content, use schema validation with Zod or TypeScript types to enforce consistent frontmatter across all posts. A validation script in your CI pipeline can catch missing fields before deployment.

Building a Visual Editing Workflow

The biggest critique of Git-based CMS is the lack of a visual editor for non-technical content authors. However, tools like TinaCMS and Decap CMS (formerly Netlify CMS) bridge this gap by providing a web-based editor that commits changes back to your Git repository. TinaCMS, in particular, offers visual in-context editing — authors click on text in a live preview and edit it directly, with changes written back to the MDX file in the repository.

For simpler workflows, use GitHub's built-in web editor. Set up a contents/ directory with clear naming conventions and descriptive frontmatter. A GitHub Actions workflow can build and preview the site on every PR, giving content authors a deployment preview URL before changes go live.

Performance Advantages of Git-Based Content

Because content is read from the filesystem (or compiled at build time), there is zero latency from a database or API call. Next.js treats MDX content as static exports, so every post can use getStaticProps with revalidate=0 for fully static output. The result is a site that loads instantly from CDN edge caches with no server-side processing for content delivery.

With Incremental Static Regeneration (ISR), updated content triggers a rebuild of only the changed page, not the entire site. This makes Git-based CMS viable for sites with thousands of pages — the build time does not scale linearly with content volume.

When a Git-Based CMS Is Not the Right Fit

Pure Git-based content management works best for developer-oriented teams and smaller editorial groups. If you have dozens of non-technical content contributors who need rich text editing, media libraries with drag-and-drop, scheduled publishing, or content workflow approvals, a traditional CMS or headless CMS like Strapi or Contentful might be more appropriate. The sweet spot for Git-based CMS is teams where the developers are the primary content authors or where the editorial team has Git comfort.

Deployment and Automation

Set up a GitHub Action (or GitLab CI equivalent) that runs a build on every push to the main branch. For content-only changes, use Next.js's unstable_revalidate or a webhook-based ISR to regenerate affected pages without a full rebuild. Vercel's framework detection automatically handles Next.js + MDX projects, providing instant rollbacks and branch previews.

A Git-based CMS with MDX gives developer-focused sites the perfect balance of flexibility and performance. SoniNow's web development team specializes in Next.js projects and can help your team adopt a Git-based content workflow that matches your workflow.