Back to Blog
Guide 2026-06-29 7 min

How to Add a CMS to a Static Site

md0 Team
Author

Static sites are fast, cheap, and easy to deploy. The downside: every content change means editing a file, committing it, and waiting for a build. For developers who write their own content, that's fine. For teams with writers who don't know Git, it's a bottleneck.

A CMS adds an editing UI on top of the existing workflow. The trick is picking a CMS that doesn't break what makes static sites worth using in the first place.

Two types of static site CMS

Before choosing a tool, you need to understand the architectural choice. Static site CMSes split into two camps based on where content lives.

API-based CMS (Contentful, Sanity, Strapi): Content lives in an external database managed by a third-party service. Your static site generator fetches that content through an HTTP API at build time. This approach works but adds a vendor dependency, an API cost, and an extra configuration layer in your SSG. If the service goes down or you cancel your subscription, your content is not in your repository.

Git-based CMS (md0, Tina, Keystatic, Decap): Content stays in your repository as markdown files. The CMS provides a visual editor that reads and writes those files through the GitHub API. There is no separate content store, no API to maintain, and no usage limits. When a writer saves a post, that action creates a Git commit. Your CI/CD pipeline picks up the commit and rebuilds the site.

For most static sites built with Gatsby, Astro, Next.js, Hugo, Jekyll, or Eleventy, a git-based CMS keeps the stack simpler. You already have markdown files in the repository. The CMS just puts an editing UI in front of them.

What to look for in a static site CMS

Not every CMS marketed at static sites is actually a good fit. Here are the criteria that matter:

Framework compatibility. Some CMSes only work with React-based sites or require a specific plugin. If you run Hugo or Jekyll, check that the tool explicitly supports your SSG before investing time in setup.

Setup time. The whole point of a static site is low operational overhead. A CMS that requires a multi-day integration project defeats that purpose. For small teams and side projects, look for something that connects in minutes, not hours.

Git integration. Content should stay in Git. This gives you version history, rollback, and the ability to drop the CMS at any time without losing content. CMSes that store content in an external database break this guarantee.

Image handling. Find out where uploaded images go. Some CMSes store images in their own CDN, which creates a dependency. Others commit images directly to the repository. Neither approach is universally better, but you should know before you start.

Cost. Most static sites are side projects or small team sites. CMS pricing that makes sense for an enterprise does not make sense for a developer blog. Look for a free tier that covers your actual usage.

Maintenance status. Two major git-based CMSes are no longer actively maintained: Forestry shut down in April 2023, and Decap CMS (formerly Netlify CMS) has sparse commit activity and a large open issue backlog as of 2025. Starting a new project on either of them is a risk.

Step-by-step: adding a git-based CMS to a static site

The steps below apply to any git-based CMS. The specifics differ by tool, but the pattern is the same.

1. Host your content on GitHub. A git-based CMS authenticates via GitHub OAuth and reads your repository through the GitHub API. A local git repository on your machine won't work. Your site needs to be in a GitHub repository, either public or private.

2. Confirm your content is markdown files. Most SSGs use markdown by default. If your content lives in a database or a proprietary format, a git-based CMS is not the right fit. You need .md or .mdx files in a directory the CMS can read.

3. Connect the CMS to your repository. With md0, this means authenticating with GitHub and selecting your repository. The CMS reads your directory structure and surfaces the markdown files as editable collections. No configuration file is required. Other tools like Keystatic require a TypeScript config file that defines your content schemas explicitly.

4. Configure which directories are editable. If the CMS does not auto-detect your content structure, point it at the directories that contain your posts or pages. For most sites this is a single directory: content/, posts/, _posts/, or src/content/.

5. Invite writers. Writers log in with their GitHub accounts and see a collection view of all content. They can create posts, edit existing ones, and upload images without touching a terminal.

6. Publish by saving. When a writer saves a post, the CMS creates a Git commit on their behalf. Your CI/CD pipeline on Vercel, Netlify, or GitHub Actions detects the new commit and triggers a rebuild. The site goes live in the same amount of time it takes to deploy any other commit.

Framework-specific notes

The setup process looks slightly different depending on your SSG.

Next.js: If you keep content in a /content/ directory and use MDX or plain markdown, md0 reads that directory directly. The App Router and Pages Router both work the same way since the CMS only cares about files, not your rendering approach.

Astro: Content collections live in /src/content/ by default. md0 edits those files directly. Your collection schemas in config.ts stay unchanged.

Hugo: Hugo expects markdown in content/ with YAML front matter. md0 handles that structure without special configuration.

Jekyll: Jekyll uses date-prefixed filenames in _posts/ (for example, 2024-01-15-my-post.md). md0 handles the filename format, so writers don't see or type those prefixes.

Eleventy: Eleventy lets you put content anywhere and configure the paths in .eleventy.js. md0 works with whatever directory structure you've already defined.

What doesn't change when you add a CMS

One concern developers raise is whether adding a CMS changes their build process or introduces dependencies that are hard to remove. With a git-based CMS, the answer to both is no.

Your build process stays the same. The static site generator reads the same files it always did. It has no knowledge of the CMS and no dependency on it.

Your Vercel or Netlify configuration stays the same. Builds still trigger on commits. The CMS just becomes the source of some of those commits.

Your markdown files remain plain .md files. If you remove the CMS tomorrow, every file is still there, exactly as it was. No export step is required, and no content is locked in a proprietary format.

Your CI/CD pipeline still triggers on commits. The CMS makes commits on behalf of writers using the GitHub API. Those commits look identical to commits made from the command line.

You can remove the CMS at any time by revoking GitHub app access. The repository is unaffected.


For more on how the git-based model works, see What Is a Git-Based CMS?.

If you're ready to connect a CMS to your site, md0 CMS is free for public repositories and takes about two minutes to set up. For framework-specific setup guides, see the guides for Next.js, Astro, Hugo, Jekyll, and Eleventy.

Ready to try md0.io?

Start writing beautiful markdown today with our free tools.

How to Add a CMS to a Static Site | md0