ELEVENTY CMS
VISUAL EDITOR
WITH md0
Eleventy is framework-agnostic and so is md0. Your .eleventy.js config stays untouched. md0 maps to whichever directories you define as collections and edits the markdown files there directly.
Why This Pairing Works
Eleventy + md0
Eleventy (11ty) is one of the most flexible static site generators available. It does not impose a specific content structure, template language, or build tool on you. You define your own directories, your own collections, your own permalink format. This flexibility is a strength, but it also means there is no standard content location for a CMS to target.
md0 handles this by letting you define collection paths using the same glob patterns you already use in your .eleventy.js config. There is no adapter plugin to install. md0 connects to your GitHub repo, you tell it which directories to manage, and it reads and writes markdown files in those directories.
Eleventy processes the markdown files at build time. md0 edits them before the build. The two tools operate at different stages of the pipeline and never conflict.
ANY FOLDER STRUCTURE
11ty lets you organize content however you want. md0 maps to it with paths. src/posts, content/blog, or any custom directory.
FRONTMATTER AS FORM
Define your 11ty front matter fields as typed schema fields. Date pickers, select dropdowns, boolean toggles replace hand-editing YAML.
ZERO CONFIG CHANGES
No .eleventy.js edits, no new npm packages, no admin directory committed to your repo. Your Eleventy setup stays exactly as it is.
PURE MARKDOWN OUTPUT
md0 writes standard Markdown with YAML front matter. Identical to what you would write by hand. No proprietary format, no lock-in.
Before You Start
Prerequisites
An Eleventy site on GitHub with markdown content
Your 11ty project needs to be in a GitHub repository. The content you want to edit must be in .md files in one or more directories.
A .eleventy.js config that defines your collections
md0 uses the same directory paths you define in .eleventy.js. Knowing which directories map to which collections makes setup straightforward.
An md0 account
Free for public repositories. Sign up at cms.md0.io using GitHub OAuth. Takes about 30 seconds.
Eleventy Content Model
How Eleventy Content Works
Eleventy does not enforce a content directory structure. You can put markdown files anywhere in your project. Eleventy processes any file in the directories you tell it to watch (configured in .eleventy.js).
Typical 11ty Directory Structures
Different Eleventy starters use different conventions. Some examples:
src/postsPosts in src/ directorypostsPosts at repo rootcontent/blogBlog contentcontent/docsDocumentationsrc/pagesStatic pagesAny of these work with md0. The path you set in md0 must match what your .eleventy.js config treats as a collection directory.
Standard Eleventy Front Matter
Eleventy reads front matter in YAML, JSON, TOML, or JavaScript. md0 writes YAML front matter, which is what most Eleventy sites use by default. Here is a typical markdown post:
src/posts/my-first-post.md
--- title: "Getting Started with Eleventy" date: 2026-01-15 tags: - eleventy - tutorial - static-site layout: post.njk permalink: /blog/getting-started/ draft: false --- Your post content goes here in standard Markdown.
Eleventy's Date Handling
Eleventy reads post dates from two places, and the precedence matters:
- 1.Front matter date field: If your file has
date: 2026-01-15, Eleventy uses that. md0 writes the date field as part of the front matter when you use a date-type field in your schema. - 2.File creation date: If there is no date in the front matter, Eleventy falls back to the file's creation timestamp. This can be unpredictable in CI environments. Use front matter dates for reliable ordering.
Tip: always include date in front matter
--- title: My Post date: 2026-01-15 ---
Global Data Files (_data/)
Eleventy's _data/ directory holds global data accessible to all templates. These are typically JSON or JS files, not markdown. md0 does not manage _data/ files. md0 focuses on markdown content files with front matter.
Step 1
Connect Your GitHub Repository
Sign in with GitHub OAuth
Go to cms.md0.io and click Sign in with GitHub. Grant md0 access to the specific repo containing your Eleventy project. You do not need to give access to all repos.
md0 requests read and write access to repository contents. It uses this to read your existing markdown files and commit changes when editors save.
Select Your Repository and Branch
After authentication, select your Eleventy repo. Choose the branch you deploy from, typically main or master.
md0 scans the repo immediately and lists every directory that contains markdown files. You will recognize your content directories from your .eleventy.js config.
Step 2
Define Collections to Match Your .eleventy.js
In .eleventy.js, you define Eleventy collections using the addCollection API. The glob patterns you use there tell Eleventy which files belong to each collection. Use those same directory paths in md0.
.eleventy.js - defining collections
module.exports = function(eleventyConfig) {
// Blog posts collection
eleventyConfig.addCollection("posts", function(collectionApi) {
return collectionApi.getFilteredByGlob("src/posts/**/*.md")
.filter(item => !item.data.draft)
.sort((a, b) => b.date - a.date)
})
// Documentation collection
eleventyConfig.addCollection("docs", function(collectionApi) {
return collectionApi.getFilteredByGlob("src/docs/**/*.md")
})
return {
dir: {
input: "src",
output: "_site",
includes: "_includes",
layouts: "_layouts",
}
}
}Map the Same Paths in md0
The glob src/posts/**/*.md means Eleventy reads all .md files in src/posts/. In md0, create a collection with path src/posts. md0 writes files into that directory. Eleventy reads them at build time. They share the same directory.
Example: posts collection schema in md0
{
"name": "posts",
"path": "src/posts",
"extension": "md",
"fields": [
{ "name": "title", "type": "text", "required": true },
{ "name": "date", "type": "date", "required": true },
{ "name": "tags", "type": "text" },
{ "name": "layout", "type": "select", "options": ["post.njk", "page.njk"], "default": "post.njk" },
{ "name": "permalink", "type": "text" },
{ "name": "draft", "type": "boolean", "default": false }
]
}Step 3
Eleventy Front Matter Fields
Eleventy reads specific front matter keys and uses them to control templating, routing, and collection membership. Map each to the right md0 field type.
title
Used in templates as {{ title }} in Nunjucks or {{ page.title }} depending on your setup. Set as a required text field in md0.
date
Controls post ordering and the item.date property in collections. Use a date field type in md0. md0 writes the value in ISO 8601 format (2026-01-15), which Eleventy parses correctly.
{ "name": "date", "type": "date", "required": true }tags
Eleventy's tagging system is how you assign posts to collections. Tags in front matter look like this:
tags: - post - tutorial - javascript
In md0, use a text field for tags. Editors write comma-separated values and md0 writes them as a YAML array. If your collection query filters by tag (for example, all items with tag post), make sure editors know which tag to use for each collection.
layout
References a file in your _layouts/ or _includes/ directory. Use a select type in md0 with the layout filenames as options. Include the extension if your files use it (post.njk, not just post).
{ "name": "layout", "type": "select", "options": ["post.njk", "page.njk", "base.njk"] }permalink
Overrides the computed URL for a page. Useful for custom slugs. Leave this as an optional text field. If blank, Eleventy generates the URL from the input file path and your global permalink config.
draft
A common pattern for keeping posts out of production. Your addCollection call filters by .filter(item => !item.data.draft). Use a boolean field in md0 with a default of false. Editors toggle it on to mark a post as draft and off to publish.
Templates
Template Languages Are Unaffected
Eleventy supports 12 template languages including Nunjucks, Liquid, Handlebars, and HTML. md0 only edits your markdown content files. Your template files in _includes/ and _layouts/ are never touched.
Nunjucks layout reading front matter
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{ title }} | My Site</title>
<meta name="description" content="{{ description }}">
</head>
<body>
<article>
<header>
<h1>{{ title }}</h1>
<time datetime="{{ date | htmlDateString }}">
{{ date | readableDate }}
</time>
{% if tags %}
<ul class="tags">
{% for tag in tags %}
<li>{{ tag }}</li>
{% endfor %}
</ul>
{% endif %}
</header>
<div class="content">
{{ content | safe }}
</div>
</article>
</body>
</html>The {{ title }}, {{ date }}, and {{ content | safe }} variables come from the markdown file's front matter and body content. md0 writes those values. Eleventy reads and injects them into the template at build time.
Liquid Shortcodes in Markdown Content
If you use Liquid shortcodes inside your markdown body (for example {% image "photo.jpg", "alt text" %}), md0 preserves them exactly as written. The visual editor treats unknown tags as plain text. When Eleventy processes the file, it runs the shortcode normally. This is expected behavior.
Step 4
Build and Deploy
Eleventy generates static HTML at build time. md0 commits content changes to GitHub. Your deployment platform watches the repo and triggers a build on every push.
Netlify
Connect your GitHub repo to Netlify. It detects Eleventy projects and sets reasonable defaults. Customize if your output directory differs.
Netlify build settings
Build command: npx @11ty/eleventy Publish directory: _site
Vercel
Vercel does not auto-detect Eleventy as a framework. Set the build command and output directory manually in your project settings.
Vercel build settings
Build command: npx @11ty/eleventy Output directory: _site
Cloudflare Pages
Cloudflare Pages supports Eleventy directly. Set the build command and select Eleventy as the framework preset.
Cloudflare Pages build settings
Framework preset: Eleventy Build command: npx @11ty/eleventy Build output directory: _site
The Full Publish Flow
Troubleshooting
Common Issues
Posts not appearing in collection
Check two things. First, confirm the md0 collection path matches exactly where your addCollection glob looks. If your glob is src/posts/**/*.md, your md0 path should be src/posts.
Second, if your collection filters by tag, confirm the new post has the correct tag in its front matter. Editors need to know which tag to use to make a post appear in a specific collection.
Posts sorted incorrectly
If posts are ordered by creation timestamp instead of the date field, make sure the date field is present in your md0 schema and that your addCollection sorts by item.date rather than filesystem order. md0 always writes the date field when it is included in the schema.
Input directory confusion
If your .eleventy.js sets dir.input to src, Eleventy reads from the src/ subdirectory, not the repo root. Your md0 paths should use the full path from the repo root. For example src/posts, not just posts.
// .eleventy.js
return {
dir: {
input: "src", // md0 path: "src/posts", not "posts"
}
}Build fails with a template error
Eleventy template errors after md0 saves usually mean a required front matter field is missing. Check which fields your Nunjucks or Liquid templates reference and confirm they are all present in your md0 schema. Any field the template reads must be included in the schema so md0 writes it to new files.
Compatibility
Works With
Nunjucks and Liquid
The two most common Eleventy template languages. md0 edits markdown content. The templates stay untouched. Front matter values pass through to templates exactly as before.
Netlify, Vercel, Cloudflare
All three platforms watch your GitHub repo and rebuild on every push. md0 commits trigger builds automatically. Build command: npx @11ty/eleventy. Output: _site.
Eleventy 2.x and 3.x
Works with both major Eleventy versions. md0 writes markdown files with YAML front matter, the same format both versions read. No version-specific changes needed.
Eleventy Starters
Works with eleventy-base-blog, eleventy-excellent, eleventy-duo, and other popular starters. If the starter reads content from markdown files in a directory, md0 works with it.
Keep Going
Next Steps
Learn the Visual Editor
md0's visual markdown editor outputs standard GitHub-flavored markdown. Editors get formatting controls, image uploads, and a live preview without ever seeing raw markdown syntax.
Visual markdown editor →Use md0 with Other Frameworks
md0 works with any static site generator that reads markdown from a Git repo.
Comparing Your Options?
- Migrating from Netlify CMS? See the comparison →
- Looking at alternatives? All CMS alternatives →
CONNECT YOUR
11TY REPO
Free for public repositories. No .eleventy.js changes. Works with any folder structure. Set up in under five minutes.
CONNECT YOUR ELEVENTY REPO