Home Blog Jekyll with a Headless CMS: Contentful, Sanity, and Decap Compared
Tutorial

Jekyll with a Headless CMS: Contentful, Sanity, and Decap Compared

Add a visual content editor to your Jekyll site without giving up static performance. A comparison of Contentful, Sanity, and Decap CMS for Jekyll.

Jekyll with a Headless CMS: Contentful, Sanity, and Decap Compared

Jekyll stores content as Markdown files — ideal for developers, frustrating for non-technical editors who want a visual dashboard. A headless CMS solves this by providing a content editing interface while keeping Jekyll as the static site builder.

Here is how the major options compare, and how to set each one up.

What is a headless CMS?

A headless CMS separates the content editing interface (“head”) from the front-end presentation. Editors log into a dashboard to write and manage content. The CMS stores content and exposes it via an API or writes it back to files. Jekyll consumes that content at build time.

The result: your editors get a friendly UI; your site is still static HTML.

Option 1: Decap CMS (formerly Netlify CMS)

Decap CMS is the most Jekyll-native option. It is an open-source, Git-based CMS — it reads and writes directly to your repository, so content stays in Markdown files alongside your code. No external API, no additional database.

How it works

Editors log into /admin/ on your site. The dashboard reads your existing Markdown files from Git, lets editors create and edit posts, and commits changes back to the repository. Your CI/CD pipeline (Netlify, Cloudflare Pages) picks up the commit and rebuilds the site.

Setup

Create admin/index.html:

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

Create admin/config.yml:

backend:
  name: git-gateway
  branch: main

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

collections:
  - name: "posts"
    label: "Blog Posts"
    folder: "_posts"
    create: true
    slug: "---"
    fields:
      - { label: "Layout", name: "layout", widget: "hidden", default: "post" }
      - { label: "Title", name: "title", widget: "string" }
      - { label: "Description", name: "description", widget: "text" }
      - { label: "Date", name: "date", widget: "datetime" }
      - { label: "Author", name: "author", widget: "string" }
      - { label: "Body", name: "body", widget: "markdown" }

Enable Identity and Git Gateway in your Netlify dashboard under Site settings → Identity.

Pros: Free, Git-based, no external API, content stays in your repository.
Cons: Requires Netlify for OAuth; limited widgets compared to commercial options.

Option 2: Contentful

Contentful is a cloud-based headless CMS with a polished editor, powerful content modelling, and a generous free tier (25,000 records, 2 users). Content is stored in Contentful’s cloud and delivered via their API.

How it works with Jekyll

Unlike Decap, Contentful does not write Markdown files — it stores content in the cloud. You use a build plugin or a custom Ruby script to fetch content from Contentful’s API at build time and generate Jekyll data files or Markdown posts.

Using a Jekyll Contentful plugin

# Gemfile
gem "jekyll-contentful-data-import"
# _config.yml
contentful:
  spaces:
    - example:
        space: YOUR_SPACE_ID
        access_token: YOUR_ACCESS_TOKEN
        cda_query:
          include: 2
        all_entries: true

Run bundle exec jekyll contentful to pull content before building. In CI, add this step to your build command:

bundle exec jekyll contentful && bundle exec jekyll build

Content arrives as YAML data files in _data/contentful/spaces/. You loop through them in Liquid like any other data:

{% for post in site.data.contentful.spaces.example.blogPost %}
<h2></h2>
{% endfor %}

Pros: Polished editor, strong content modelling, free tier is generous, good for large teams.
Cons: Content lives in the cloud (not your repo), API dependency at build time, can be complex to set up.

Option 3: Sanity

Sanity is a flexible, API-first headless CMS with a real-time collaborative editor (Sanity Studio) you can customise with JavaScript. It is particularly popular for structured content and complex content models.

How it works with Jekyll

Sanity stores content in its cloud. You fetch it at build time using a Ruby script or the Sanity JavaScript client.

Install the Sanity CLI and create a project:

npm create sanity@latest

Fetch content at build time with a Node.js script:

// tools/fetch-sanity.js
const { createClient } = require("@sanity/client");
const fs = require("fs");
const path = require("path");

const client = createClient({
  projectId: "YOUR_PROJECT_ID",
  dataset: "production",
  useCdn: true,
  apiVersion: "2024-01-01",
});

async function fetchPosts() {
  const posts = await client.fetch(`*[_type == "post"]{title, slug, body, publishedAt}`);
  
  posts.forEach(post => {
    const content = `---
layout: post
title: "${post.title}"
date: ${post.publishedAt}
---

${post.body}`;
    
    const filename = `${post.publishedAt.split("T")[0]}-${post.slug.current}.md`;
    fs.writeFileSync(path.join("_posts", filename), content);
  });
  
  console.log(`Fetched ${posts.length} posts`);
}

fetchPosts();

Add to your build command:

node tools/fetch-sanity.js && bundle exec jekyll build

Pros: Extremely flexible content model, real-time collaboration, excellent for complex structured content.
Cons: More setup than Decap, content not in your repo, costs money beyond the free tier.

Comparison table

  Decap CMS Contentful Sanity
Content storage Git (your repo) Cloud Cloud
Free tier Free (open source) 25k records, 2 users Up to 3 users
Setup complexity Low Medium Medium-High
Editor experience Good Excellent Excellent
Content modelling YAML config Drag-and-drop JavaScript
Real-time collab No Yes (paid) Yes
Best for Small teams, developers Mid-size teams Complex content

Which should you choose?

Choose Decap CMS if: Your team is small, you want content in Git, you are already on Netlify, and you want zero additional infrastructure cost.

Choose Contentful if: You have non-technical editors who need a polished experience, your content model is straightforward, and you want a managed solution with a free tier.

Choose Sanity if: You need a highly customised editing experience, complex structured content with references and blocks, or real-time collaboration out of the box.

For most Jekyll sites with one or two editors, Decap CMS is the right choice — it is free, keeps content in Git, and requires no external API at build time.

Share LinkedIn