Adding a CMS to Your Static Site With Netlify CMS
If you're looking for a developer-friendly CMS platform for creating static sites, check out this article on a CMS with a growing community of devs.
Join the DZone community and get the full member experience.
Join For FreeFor nearly seven years I was a CMS implementer and contributor, mostly with Drupal, but occasionally with Joomla! and WordPress. Then about 3 years ago I encountered Jekyll and I had a revelation, a system that let me manage and render content, but in a manner that suited me as a writer, using markup formats such as markdown, reStructuredText, and Asciidoc. Whilst the plain text and version control approach is great for some, and despite best efforts from vendors such as GitHub and GitLab, it’s still not that accessible to less technically minded people. Many projects have attempted to bridge this gap and merge the best of the two worlds, from commercial SaaS providers such as Contentful, Prismic, or CloudCannon to open source options like Cockpit and getmesh.
Just over a year ago, Netlify, the fantastic host for static sites announced ‘Netlify CMS’ and it looked promising, adding a CMS-like interface to the git workflow. I made some initial investigations, but now finally have time for a proper dive into how to set it up and use it.
I will use Netlify CMS (NC) with Jekyll, but you can find instructions on how to add it to other existing static sites or get started from scratch with a new site.
Adding Netlify CMS to Jekyll
Create an admin folder with an index.html and a config.yml file; these act as the gateway to your admin interface and the settings behind it, respectively.
Inside index.html, add the skeleton HTML, JavaScript, and CSS needed to create the admin interface, for full custom branding, you can add links to your style sheets too, but as this is an admin ‘backend,’ you may not need them.
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Content Manager</title>
<!-- Add your own styles here -->
<link rel="stylesheet" href="https://unpkg.com/netlify-cms@^1.0.0/dist/cms.css" />
</head>
<body>
<!-- Include the script that builds the page and powers Netlify CMS -->
<script src="https://unpkg.com/netlify-cms@^1.0.0/dist/cms.js"></script>
</body>
</html>
Naturally, the configuration file varies for your use case, but I’ll show you what I use for my ‘Gregarious Mammal’ site, and you can extrapolate from there.
First, determine the backend type and if users need to authenticate to access it, you can use users defined in Netlify, or in GitHub (those with push access). I want to allow users to change content outside of Netlify, so use the GitHub method:
backend:
name: github
repo: GregariousMammal/Main-Site # Path to Github repository
branch: master # Branch to update
To define which users can access the admin backend and edit content I recommend you read Netlify’s steps. You can authenticate with a variety of different methods, or handle the process via Netlify’s identity service that you might have setup already (I do).
If you add the setting below, then posts go through a workflow process where specific users can review and edit posts held in pull requests until you publish them. Otherwise, NC commits posts to the branch defined above.
publish_mode:editorial_workflow
The site uses lots of images, and I want people to add an image with every post, so you need to define where to store them, add that with the media_folder
parameter, and also public_folder
that sets where to serve images from:
media_folder:"images"# Media files will be stored in the repo under images
public_folder:"/images"# The src attribute for uploaded media will begin with /images
I did find some issues with images I had stored in sub-folders, there is an issue discussing sub-folders, but I’m unsure if it’s related.
Now comes the most complicated part. My site has a lot of different ‘content types’ to represent different items of content, sometimes using collections and sometimes using different fields in different places. This section will be the section of your configuration and consists of a series of YAML sections representing your content. The general structure is:
collections:
- name: "posts" # Used in routes, e.g. /admin/collections/blog
label: "Posts" # Used in the UI
folder: "_posts" # The path to the folder where the documents are stored
create: true # Allow users to create new documents in this collection
slug: "{{year}}-{{month}}-{{day}}-{{slug}}" # Filename template i.e. YYYY-MM-DD-title.md
filter:
- field: publication_url
- value: ""
fields: # The fields for each document, usually in front matter
- {label: "Layout", name: "layout", widget: "hidden", default: "post"}
- {label: "Title", name: "title", widget: "string"}
- {label: "Publish Date", name: "date", widget: "datetime"}
- {label: "Featured Image", name: "image", widget: "image"}
- {label: "Categories", name: "categories", widget: "string"}
- {label: "Tags", name: "tags", widget: "string"}
- {label: "Body", name: "body", widget: "markdown"}
- {label: "Publication URL", name: "publication_url", widget: "string"}
You can use one of about 12 default widgets, and it’s not too hard to create your own if you know React. By default, fields are set as required
, so add required: false
if they are not in your content model, i.e.:
-{label: "Publication URL", name: "publication_url", widget: "string", required: false}
My site has a lot of content, and I couldn’t get Netlify CMS to load it all - this might be limits with JavaScript calls or the GitHub API. There’s probably a way to fix this, but as a lot of the posts are autogenerated stub files for aggregated content, I don’t need to edit them anyway. Netlify CMS offers a way to filter these using the filter
property on a field value.
filter:
- field: language
- value: en
I wanted to filter by date to load the most recent posts, but that wasn’t possible, so I tried to filter posts that didn’t have a publication_url
but didn’t have much luck getting filters to work, your mileage may vary. There are also limits on how much you can pull from the GitHub API, so I might need to reorganize my content into more collections or sub-folders.
You can see the complete content types for my site here.
Using Netlify CMS
Fire up your static site generator as normal and visit _admin. You should see sections for each of the content types you defined, plus one for media and workflow (if enabled).
The interface has limited filter and sort options, but there is a search box. You use the add buttons to create content with a handy GUI and preview it. When you click save, posts are held in a pull request until you publish them when they are then merged into the master. There’s a summary here of what GUI action results in what git action.
SSCMS (Static Site CMS!)
In my opinion, Netlify has, so far, made the best effort to create a CMS-like front-end for static sites that suits the workflows of technical and non-technical users. It’s early days with bugs and features needed, but with the strength of the Netlify commercial product and community drive, I hold a lot of hope for its development.
Opinions expressed by DZone contributors are their own.
Comments