Home Blog How to Add a CMS to Jekyll with Decap CMS (Formerly Netlify CMS)
Tutorial

How to Add a CMS to Jekyll with Decap CMS (Formerly Netlify CMS)

Add a visual content editor to your Jekyll site using Decap CMS — set up the admin panel, configure collections, and let non-developers publish posts without touching code.

How to Add a CMS to Jekyll with Decap CMS (Formerly Netlify CMS)

Jekyll is code-first — posts are Markdown files, publishing means a Git commit. That’s great for developers but a barrier for non-technical collaborators. Decap CMS (the open-source successor to Netlify CMS) adds a visual editing interface to any Jekyll site, backed by your Git repository. No database, no separate server.


What Is Decap CMS?

Decap CMS is an open-source, Git-based content management system. It adds an /admin page to your site with a visual editor. When a content editor saves a post, Decap CMS commits the Markdown file to your GitHub repository — the same way you would from the command line, but through a web interface.

Key points:

  • Runs entirely in the browser — no server needed
  • Saves content as Markdown files in your repository
  • Authenticates via GitHub, GitLab, or Bitbucket OAuth
  • Free and open-source (MIT licence)
  • Works with GitHub Pages, Netlify, and Cloudflare Pages

Step 1: Create the Admin Folder

Create an admin/ folder in your Jekyll site root with two files:

admin/index.html:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta name="robots" content="noindex">
  <title>Content Manager</title>
</head>
<body>
  <script src="https://unpkg.com/decap-cms@^3.0.0/dist/decap-cms.js"></script>
</body>
</html>

admin/config.yml:

This is the main configuration file — it defines your content collections and fields.


backend:
  name: github
  repo: yourusername/your-repo-name
  branch: main

media_folder: "assets/images/uploads"
public_folder: "/assets/images/uploads"

collections:
  - name: "posts"
    label: "Blog Posts"
    folder: "_posts"
    create: true
    slug: "{{year}}-{{month}}-{{day}}-{{slug}}"
    fields:
      - { label: "Title", name: "title", widget: "string" }
      - { label: "Description", name: "description", widget: "string" }
      - { label: "Date", name: "date", widget: "datetime" }
      - { label: "Cover Image", name: "image", widget: "image", required: false }
      - { label: "Author", name: "author", widget: "string", required: false }
      - { label: "Category", name: "category", widget: "string", required: false }
      - label: "Tags"
        name: "tags"
        widget: "list"
        field: { label: "Tag", name: "tag", widget: "string" }
      - { label: "Featured", name: "featured", widget: "boolean", default: false }
      - { label: "Body", name: "body", widget: "markdown" }


Step 2: Set Up Authentication

Decap CMS needs a way to authenticate with GitHub. Choose one:

Option A: Netlify Identity (Easiest, Netlify only)

If your site is on Netlify:

  1. Enable Netlify Identity in your site’s Netlify dashboard → Identity → Enable
  2. Under Registration preferences, set to Invite only
  3. Under External providers, enable GitHub
  4. Add the Netlify Identity widget to your site:

In admin/index.html, add before </head>:

<script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>

Also add to your _layouts/default.html before </body>:

<script>
  if (window.netlifyIdentity) {
    window.netlifyIdentity.on("init", user => {
      if (!user) {
        window.netlifyIdentity.on("login", () => {
          document.location.href = "/admin/";
        });
      }
    });
  }
</script>
<script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>
  1. Invite users in Netlify → Identity → Invite users

Option B: GitHub OAuth App (Works on any host)

  1. Go to GitHub → Settings → Developer settings → OAuth Apps → New OAuth App
  2. Set:
    • Application name: Your Site CMS
    • Homepage URL: https://yourdomain.com
    • Authorization callback URL: https://api.netlify.com/auth/done
  3. Copy the Client ID and Client Secret
  4. In Netlify Dashboard → Site settings → Access control → OAuth → Install provider → GitHub → paste Client ID and Secret

Update admin/config.yml:

backend:
  name: github
  repo: yourusername/your-repo-name
  branch: main
  base_url: https://api.netlify.com
  auth_endpoint: auth

Step 3: Configure Your Collections

A collection maps to a folder of content files. Configure one for each content type you want editors to manage.

Posts Collection


- name: "posts"
  label: "Blog Posts"
  folder: "_posts"
  create: true
  slug: "{{year}}-{{month}}-{{day}}-{{slug}}"
  preview_path: "blog/{{slug}}"
  fields:
    - { label: "Layout", name: "layout", widget: "hidden", default: "post" }
    - { label: "Title", name: "title", widget: "string" }
    - { label: "Description", name: "description", widget: "string", hint: "150-160 characters for SEO" }
    - { label: "Publish Date", name: "date", widget: "datetime" }
    - { label: "Cover Image", name: "image", widget: "image", required: false }
    - label: "Category"
      name: "category"
      widget: "select"
      options: ["Tutorial", "Blog", "Themes", "SEO", "Comparison"]
    - label: "Tags"
      name: "tags"
      widget: "list"
    - { label: "Featured Post", name: "featured", widget: "boolean", default: false }
    - { label: "Body", name: "body", widget: "markdown" }

Pages Collection

- name: "pages"
  label: "Pages"
  files:
    - label: "About"
      name: "about"
      file: "_pages/about.md"
      fields:
        - { label: "Title", name: "title", widget: "string" }
        - { label: "Body", name: "body", widget: "markdown" }
    - label: "Contact"
      name: "contact"
      file: "_pages/contact.md"
      fields:
        - { label: "Title", name: "title", widget: "string" }
        - { label: "Body", name: "body", widget: "markdown" }

Themes Collection (for JekyllHub)


- name: "themes"
  label: "Themes"
  folder: "_themes"
  create: true
  slug: "{{slug}}"
  fields:
    - { label: "Title", name: "title", widget: "string" }
    - { label: "Description", name: "description", widget: "text" }
    - { label: "Demo URL", name: "demo_url", widget: "string" }
    - { label: "GitHub URL", name: "github_url", widget: "string" }
    - { label: "Stars", name: "stars", widget: "number" }
    - label: "Price Type"
      name: "price_type"
      widget: "select"
      options: ["free", "premium"]
    - { label: "Card Image", name: "card_image", widget: "image" }
    - { label: "Body", name: "body", widget: "markdown" }


Step 4: Add admin/ to Your Build

Make sure the admin/ folder is included in your Jekyll build. By default it is — Jekyll copies non-underscored folders to _site/.

If you have a .gitignore that excludes admin/, remove that exclusion.

Verify by running bundle exec jekyll build and checking that _site/admin/index.html exists.


Step 5: Exclude admin from Sitemap

You don’t want the admin panel showing up in your sitemap or search results:

# admin/index.html front matter (add front matter to the file)
---
sitemap: false
---

Or in _config.yml:

exclude:
  - admin/config.yml

Using the CMS

Once set up, your editors visit https://yourdomain.com/admin/ and log in with GitHub. They see a dashboard with all your configured collections.

Creating a post: Click the collection, click New Post, fill in the fields, write in the Markdown editor, click Publish. Decap CMS commits the file to your repository, triggering a rebuild.

Editing existing content: Browse the collection, click a file, edit, save.

Media uploads: Images drag-and-drop into the Markdown editor and are saved to your assets/images/uploads/ folder.


Editorial Workflow (Optional)

Enable draft/review workflow so posts go through approval before publishing:

# admin/config.yml
publish_mode: editorial_workflow

This adds a Kanban-style board with Drafts, In Review, and Ready columns. Content stays as a branch until approved, then merges to main.


Alternatives to Decap CMS

Tool Price Best for
Decap CMS Free Git-based, self-hosted
CloudCannon $45+/month Most polished Jekyll CMS
Forestry.io Free (limited) Simple visual editing
TinaCMS Free (limited) Real-time inline editing
Contentful Free (limited) API-first, enterprise

For most Jekyll sites, Decap CMS hits the right balance of features and cost (free). CloudCannon is worth it if you’re managing content for clients or a team.


Browse Jekyll themes on JekyllHub — all themes work with Decap CMS as the admin panel.

Share LinkedIn