Examples

Do you have a great, open source example? Submit a pull request to this page!

Example  Tools  Type  Source  More info Gatsby & Netlify CMS Meetup Group Template  Gatsby  demo  robertcoopercode/gatsby-netlify-cms  blog post This Developing Journey  middleman  blog  bdougie/blog  blog post Jamstack Recipes  Hugo, Azure  demo  hlaueriksson/jamstack-cms  blog post Bael  Vue, Nuxt  blog  jake-101/bael-template  blog post Forest Garden Wales  Hugo  blog  forestgardenwales/forestgarden.wales  blog post Jekyll Demo  Jekyll, Gulp  demo  NickStees/jekyll-cms  read me Jekyll feat Alembic Theme Demo  Jekyll  demo  DavidDarnes/alembic-netlifycms-kit  read me Eleventy Starter Project  Eleventy  demo  danurbanowicz/eleventy-netlify-boilerplate  read me YellowCake – Complete website with blog  Gatsby, Netlify-CMS, Uploadcare  demo  thriveweb/yellowcake  blog post Vue.js – Nuxt.js Starter Project  Vue, Nuxt  demo  renestalder/nuxt-netlify-cms-starter-template  read me Hexo Demo  Hexo  demo  DemoMacro/Hexo-NetlifyCMS  read me Gitbook Demo  Gitbook  demo  DemoMacro/Gitbook-NetlifyCMS  read me VuePress Demo  VuePress  demo  DemoMacro/VuePress-NetlifyCMS  read me Jigsaw Blog Starter Template Demo  Jigsaw  demo  erickpatrick/jigsaw-blog-netlify-netlifycms-template  blog post Nuxt & NetlifyCMS Boilerplate  Vue, Nuxt  demo  tylermercer/nuxt-netlifycms-boilerplate  read me Next.js demo  Next.js  blog  masives/netlifycms-nextjs  read me Delog – Jamstack Blog with Netlify CMS  Gatsby, Netlify-CMS  demo  W3Layouts/gatsby-starter-delog  blog post Netlify CMS template for Gridsome  Gridsome, Vue  demo  suits-at/netlifycms-gridsome  read me Next.js blogging template for Netlify  Next.js, Netlify  blog  wutali/nextjs-netlify-blog-template  read me Netlify CMS and OAuth server on AWS  Netlify, Pulumi, AWS  blog  pulumi/examples/aws-ts-netlify-cms-and-oauth  blog post Eleventy Starter Boilerplate  Eleventy, Netlify  demo  ixartz/Eleventy-Starter-Boilerplate  read me Nuxt, Tailwind & NetlifyCMS Boilerplate  Vue, Nuxt  demo  Knogobert/ntn-boilerplate  read me Gatsby & Netlify CMS Personal Portfolio  Gatsby  portfolio  EarlGeorge/React-Gatsby  read me Gatsby, Tailwind CSS & NetlifyCMS Starter  Gatsby v3, Netlify-CMS, Tailwind CSS  demo  jimmybutton/gatsby-netlifycms-tailwind-starter  read me Metalsmith NetlifyCMS Starter  Metalsmith and Netlify-CMS  demo  metalsmith-netlify-starter  read me

Update the CMS Version

The update procedure for your CMS depends upon the method you used to install Netlify CMS.
Package Manager

If you are using a package manager like Yarn or NPM, use their standard procedure to update. This is how both the Hugo and Gatsby starters are set up.

CDN

If you are using the CMS through a CDN like Unpkg, then that depends on the version tag you are using. You can find the version tag in the /admin/index.html file of your site.

(Recommended) If you use ^2.0.0, the CMS does all updates except major versions automatically.
It upgrades to 2.0.1, 2.1.0, 2.1.2.
It does not upgrade to 3.0.0 or higher.
It does not upgrade to beta versions.

If you use ~2.0.0, the CMS will do only patch updates automatically.
It upgrades 2.0.1, 2.0.2.
It does not upgrade to 2.1.0 or higher.
It does not upgrade beta versions.

Uploadcare

Uploadcare is a sleek service that allows you to upload files without worrying about maintaining a growing collection — more of an asset store than a library. Just upload when you need to, and the files are hosted on their CDN. They provide image processing controls from simple cropping and rotation to filters and face detection, and a lot more. You can check out Uploadcare’s full feature set on their website.

The Uploadcare media library integration for Netlify CMS allows you to use Uploadcare as your media handler within the CMS itself. It’s available by default as of our 2.1.0 release, and works in tandem with the existing file and image widgets, so using it only requires creating an Uploadcare account and updating your Netlify CMS configuration.

Please make sure that Netlify CMS is updated to 2.1.0 or greater before proceeding.
Creating an Uploadcare Account

You can sign up for a free Uploadcare account to get started. Once you’ve signed up, go to your dashboard, select a project, and then select “API keys” from the menu on the left. The public key on the API keys page will be needed in your Netlify CMS configuration. For more info on getting your API key, visit their walkthrough.
Updating Netlify CMS Configuration

The next and final step is updating your Netlify CMS configuration file:

Add a media_library property at the same level as media_folder, with an object as it’s value.
In the media_library object, add the name of the media player under name.
Add a config object under name with a publicKey property with your Uploadcare public key as it’s value.

Your config.yml should now include something like this (except with a real API key):

media_library:
name: uploadcare
config:
publicKey: YOUR_UPLOADCARE_PUBLIC_KEY

Once you’ve finished updating your Netlify CMS configuration, the Uploadcare widget will appear when using the image or file widgets.

Note: The Netlify CMS media library extensions for Uploadcare are not included in netlify-cms-app. If you’re using netlify-cms-app, you’ll need to register the media libraries yourself.
Configuring the Uploadcare Widget

The Uploadcare widget can be configured with settings that are outlined in their docs. The widget itself accepts configuration through global variables and data properties on HTML elements, but with Netlify CMS you can pass configuration options directly through your config.yml.

Note: all default values described in Uploadcare’s documentation also apply in the Netlify CMS integration, except for previewStep, which is set to true. This was done because the preview step provides helpful information like upload status, and provides access to image editing controls. This option can be disabled through the configuration options below.
Global configuration

Global configuration, which is meant to affect the Uploadcare widget at all times, can be provided as seen above, under the primary media_library property. Settings applied here will affect every instance of the Uploadcare widget.
Field configuration

Configuration can also be provided for individual fields that use the media library. The structure is very similar to the global configuration, except the settings are added to an individual field. For example:


fields:
name: cover
label: Cover Image
widget: image
media_library:
config:
multiple: true
previewStep: false

Integration settings

There are several settings that control the behavior of integration with the widget.

autoFilename (boolean) – specify whether to add a filename to the end of the url. Example: http://ucarecdn.com/:uuid/filename.png
defaultOperations (string) – specify a string added at the end of the url. This could be useful to apply a set of CDN operations to each image, for example resizing or compression. All the possible operations are listed here.

media_library:
name: uploadcare
config:
publicKey: YOUR_UPLOADCARE_PUBLIC_KEY
settings:
autoFilename: true
defaultOperations: ‘/resize/800×600/’

Quick Start

There are many ways to add Netlify CMS to your static site. This guide will take you through one of the quickest methods, which takes advantage of Netlify’s hosting and authentication provider services.
Storage and Authentication

Netlify CMS relies on the GitHub API for managing files, so you’ll need to have your site stored in a GitHub repo. (If you’re partial to another Git hosting service, you can file a feature request, or help us add it.) To connect to the repo and make changes, the app needs to authenticate with the GitHub API. You can roll your own service for doing this, but we’re going to use Netlify in this example.
Hosting with Netlify

In order to use Netlify’s authentication provider service, you’ll need to connect your site repo with Netlify. Netlify has published a general Step-by-Step Guide for this, along with detailed guides for many popular static site generators, including Jekyll, Hugo, Hexo, Middleman, Gatsby and more.
Authenticating with GitHub

In order to connect Netlify CMS with your GitHub repo, you’ll first need to register it as an authorized application with your GitHub account:

Go to your account Settings page on GitHub, and click Oauth Applications under Developer Settings (or use this shortcut).
Click Register a new application.
For the Authorization callback URL, enter https://api.netlify.com/auth/done. The other fields can contain anything you want.

GitHub Oauth Application setup example

When you complete the registration, you’ll be given a Client ID and a Client Secret for the app. You’ll need to add these to your Netlify project:

Go to your Netlify dashboard and click on your project.
Click the Access tab.
Under Authentication Providers, click Install Provider.
Select GitHub and enter the Client ID and Client Secret, then save.

App File Structure

All Netlify CMS files are contained in a static admin folder, stored at the root of the generated site. Where you store this in the source files depends on your static site generator. Here’s the the static file location for a few of the most popular static site generators:
These generators …     store static files in
Jekyll, GitBook     / (project root)
Hugo, Gatsby*     /static
Hexo, Middleman     /source
Spike     /views

Notes: – Gatsby treats the static folder more strictly and will not render the admin page as the other generators. You will have to make a page component containing the necessary scripts of the Netlify CMS app in the admin page. However, the config.yml is to be placed in the static folder in the same way.

If your generator isn’t listed here, you can check its documentation, or as a shortcut, look in your project for a CSS or images folder. They’re usually processed as static files, so it’s likely you can store your admin folder next to those. (When you’ve found the location, feel free to add it to these docs by filing a pull request!).

Inside the admin folder, you’ll create two files:

admin
├ index.html
└ config.yml

The first file, admin/index.html, is the entry point for the Netlify CMS admin interface. This means that users can navigate to yoursite.com/admin to access it. On the code side, it’s a basic HTML starter page that loads the necessary CSS and JavaScript files. In this example, we pull those files from a public CDN:

<!doctype html>
<html>
<head>
<meta charset=”utf-8″ />
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″ />
<title>Content Manager</title>

<link rel=”stylesheet” href=”https://unpkg.com/netlify-cms@~0.4/dist/cms.css” />

</head>
<body>
<script src=”https://unpkg.com/netlify-cms@~0.4/dist/cms.js”></script>
</body>
</html>

The second file, admin/config.yml, is the heart of your Netlify CMS installation, and a bit more complex. The next section covers the details.
Configuration

Configuration will be different for every site, so we’ll break it down into parts. All code snippets in this section will be added to your admin/config.yml file.
Backend

Because we’re using GitHub and Netlify for our hosting and authentication, backend configuration is fairly strightforward. You can start your config.yml file with these lines:

backend:
name: github
repo: owner-name/repo-name # Path to your Github repository
branch: master # Branch to update

This names GitHub as the authentication provider, points to the repo location on github.com, and declares the branch where you want to merge changes. If you leave out the branch declaration, it will default to master.
Editorial Workflow

By default, saving a post in the CMS interface will push a commit directly to the branch specified in backend. However, you also have the option to enable the Editorial Workflow, which adds an interface for drafting, reviewing, and approving posts. To do this, simply add the following line to your config.yml:

publish_mode: editorial_workflow

Media and Public Folders

Netlify CMS allows users to upload images directly within the editor. For this to work, the CMS needs to know where to save them. If you already have an images folder in your project, you could use its path, possibly creating an uploads sub-folder, for example:

media_folder: “images/uploads” # Media files will be stored in the repo under images/uploads

If you’re creating a new folder for uploaded media, you’ll need to know where your static site generator expects static files. You can refer to the paths outlined above in App File Structure, and put your media folder in the same location where you put the admin folder.

Note that themedia_folder file path is relative to the project root, so the example above would work for Jekyll, GitBook or any other generator that stores static files at the project root. It would not, however, work for Hugo, Hexo, Middleman or others that use a different path. Here’s an example that could work for a Hugo site:

media_folder: “static/images/uploads” # Media files will be stored in the repo under static/images/uploads
public_folder: “/images/uploads” # The src attribute for uploaded media will begin with /images/uploads

This configuration adds a new setting, public_folder. While media_folder specifies where uploaded files will be saved in the repo, public_folder indicates where they can be found in the generated site. This path is used in image src attributes and is relative to the file where it’s called. For this reason, we usually start the path at the site root, using the opening /.

If public_folder is not set, Netlify CMS will default to the same value as media_folder, adding an opening / if one is not included.

Collections

Collections define the structure for the different content types on your static site. Since every site is different, the collections settings will be very different from one site to the next.

Let’s say your site has a blog, with the posts stored in _posts/blog, and files saved in a date-title format, like 1999-12-31-lets-party.md. Each post begins with settings in yaml-formatted front matter, like so:


layout: blog
title: “Let’s Party”
date: 1999-12-31 11:59:59 -0800
thumbnail: “/images/prince.jpg”
rating: 5

This is the post body, where I write about our last chance to party before the Y2K bug destroys us all.

Given this example, our collections settings would look like this:

collections:
– name: “blog” # Used in routes, e.g., /admin/collections/blog
label: “Blog” # Used in the UI
folder: “_posts/blog” # 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, e.g., YYYY-MM-DD-title.md
fields: # The fields for each document, usually in front matter
– {label: “Layout”, name: “layout”, widget: “hidden”, default: “blog”}
– {label: “Title”, name: “title”, widget: “string”}
– {label: “Publish Date”, name: “date”, widget: “datetime”}
– {label: “Featured Image”, name: “thumbnail”, widget: “image”}
– {label: “Rating (scale of 1-5)”, name: “rating”, widget: “number”}
– {label: “Body”, name: “body”, widget: “markdown”}

Let’s break that down:
name     Post type identifier, used in routes. Must be unique.
label     What the post type will be called in the admin UI.
folder     Where files of this type are stored, relative to the repo root.
create     Set to true to allow users to create new files in this collection.
slug     Template for filenames. {{year}}, {{month}}, and {{day}} will pull from the post’s date field or save date. {{slug}} is a url-safe version of the post’s title. Default is simply {{slug}}.
fields     Fields listed here are shown as fields in the content editor, then saved as front matter at the beginning of the document (except for body, which follows the front matter). Each field contains the following properties:

label: Field label in the editor UI.
name: Field name in the document front matter.
widget: Determines UI style and value data type (details below).
default (optional): Sets a default value for the field.

As described above, the widget property specifies a built-in or custom UI widget for a given field. The first field in the example, layout, uses a hidden widget. This widget will not show in the editor UI, but will be saved with the default value (assuming it’s been set) in the document front matter. The rest of the widgets work as follows:
Widget     UI     Data Type
string     text input     string
datetime     date picker widget     ISO date string
image     file picker widget with drag-and-drop     file path saved as string, image uploaded to media folder
number     text input with + and – buttons     number
markdown     rich text editor with raw option     markdown-formatted string

Based on this example, you can go through the post types in your site and add the appropriate settings to your config.yml file. Each post type should be listed as a separate node under the collections field.
Filter

The entries for any collection can be filtered based on the value of a single field. The example collection, below, would only show post entries with the value “en” in the language field.

collections:
– name: “posts”
label: “Post”
folder: “_posts”
filter:
field: language
value: en
fields:
– {label: “Language”, name: “language”}

Accessing the App

With your configuration complete, it’s time to try it out! Go to yoursite.com/admin and complete the login prompt to access the admin interface. To add users, simply add them as collaborators on the GitHub repo.

Happy posting!

NextJS

This guide will help you get started using Netlify CMS with NextJS.

Creating a new project

Let’s repeat some of the basics of setting up a simple NextJS project (check out nextjs.org/learn for a more detailed version).

# Create new directory and navigate into it
mkdir awesome-kitties
cd awesome-kitties

# Initialize a new project
npm init -y

# Install required dependencies
npm install --save react react-dom next

# Install webpack loader for Markdown (Use version 3+)
npm install --save-dev frontmatter-markdown-loader

# If using NextJS v11.0.0 or above, @babel/core and @babel/preset-react has to be installed as dependencies of frontmatter-markdown-loader
npm install --save-dev @babel/core @babel/preset-react

# Create folder for pages (default for NextJS), and add a index file
mkdir pages
touch pages/index.js

# Create a folder for content, and a markdown file:
mkdir content
touch content/home.md

# Create a folder for static assets
mkdir public

Next, we need to add some modifications to our package.json file to make it easier to run and deploy our new site:

{
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start",
    "export": "npm run build && next export"
  }
}

There is a lot of different ways to create and display Markdown content, but to make this as easy as possible we’ll be using a webpack-loader that enables us to load markdown files directly in our React components (frontmatter-markdown-loader).

Add the following content to your content/home.md file:

---
title: Awesome kitties
date: 2019-03-17T19:31:20.591Z
cats:
  - description: 'Maru is a Scottish Fold from Japan, and he loves boxes.'
    name: Maru (まる)
  - description: Lil Bub is an American celebrity cat known for her unique appearance.
    name: Lil Bub
  - description: 'Grumpy cat is an American celebrity cat known for her grumpy appearance.'
    name: Grumpy cat (Tardar Sauce)
---
Welcome to my awesome page about cats of the internet.

This page is built with NextJS, and content is managed in Netlify CMS

Next, we need to tell webpack how to load Markdown files. Create a new next.config.js file at the root of your project with the following content:

module.exports = {
    webpack: (cfg) => {
        cfg.module.rules.push(
            {
                test: /\.md$/,
                loader: 'frontmatter-markdown-loader',
                options: { mode: ['react-component'] }
            }
        )
        return cfg;
    }
}

Almost there! The last thing we need to do is to add some content to our pages/index.js file. With a little help of our webpack loader, we can now easily import Markdown files:

import Head from "next/head"
import { Component } from 'react'
import { attributes, react as HomeContent } from '../content/home.md';

export default class Home extends Component {
  render() {
    let { title, cats } = attributes;
    return (
      <>
        <Head>
          <script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>
        </Head>
        <article>
          <h1>{title}</h1>
          <HomeContent />
          <ul>
            {cats.map((cat, k) => (
              <li key={k}>
                <h2>{cat.name}</h2>
                <p>{cat.description}</p>
              </li>
            ))}
          </ul>
        </article>
      </>
    )
  }
}

Great! We now have a page that displays content from our Markdown file. Go ahead and start your development server to test if everything is working:

npm run dev

Adding Netlify CMS

There are many different ways to add Netlify CMS to your project. The easiest is probably just to embed it from a CDN, and that’s exactly what we’re gonna do. To avoid making this guide too complicated, we’re just going to add Netlify into a subfolder inside the /public directory (which is just served as static files by Next):

# Create and navigate into public/admin folder
mkdir -p public/admin
cd public/admin

# Create index.html and config.yml file
touch index.html
touch config.yml

Paste HTML for Netlify CMS into your public/admin/index.html file (check out the Add Netlify To Your Site section for more information)

<!doctype html>
<html>
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Content Manager</title>
  <script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>
</head>
<body>
  <!-- Include the script that builds the page and powers Netlify CMS -->
  <script src="https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js"></script>
</body>
</html>

Notice that we also added the identity widget. This allows sign up when the project is hosted at Netlify.

Paste the following configuration into your public/admin/config.yml file:

backend:
  name: git-gateway
  branch: main # Branch to update (optional; defaults to master)
media_folder: public/img
public_folder: img
collections:
  - name: "pages"
    label: "Pages"
    files:
    - label: "Home"
      name: "home"
      file: "content/home.md"
      fields:
        - { label: "Title", name: "title", widget: "string"}
        - { label: "Publish Date", name: "date", widget: "datetime" }
        - { label: "Body", name: "body", widget: "markdown"}
        - label: 'Cats'
          name: "cats"
          widget: list
          fields:
            - { label: "Name", name: "name", widget: "string"}
            - { label: "Description", name: "description", widget: "text"}

Awesome! Netlify CMS should now be available at localhost:3000/admin/index.html. Unfortunately we can’t edit our content just yet. First we need to move our code into a git repository, and create a new Netlify site.

Tip: If you want to test changes made to your config.yml file locally, swap out “git-gateway” with “test-repo” and navigate to localhost:3000/admin/index.html to view Netlify CMS locally (you can’t make changes or read actual content from Git this way, but it’s great to verify how things will look).

Publishing to GitHub and Netlify

Create a new repository at GitHub (or one of the other supported git services) and follow the instructions on how to push existing files into your new repository.

Now is probably also a good time to add a .gitignore file:

.next/
node_modules/
/npm-debug.log
.DS_Store
out/

When your project is under version control, go to Netlify and select “New Site from Git”. Select GitHub (or whatever service you used in the previous step), and the repository you just pushed to.

Under the final step (Build options, and deploy!), make sure you enter the following:

Field Value
Build command npm run export
Publish directory out

Enable Identity and Git Gateway

Netlify’s Identity and Git Gateway services allow you to manage CMS admin users for your site without requiring them to have an account with your Git host or commit access on your repo. From your site dashboard on Netlify:

  1. Go to Settings > Identity, and select Enable Identity service.
  2. Under Registration preferences, select Open or Invite only. In most cases, you want only invited users to access your CMS, but if you’re just experimenting, you can leave it open for convenience.
  3. If you’d like to allow one-click login with services like Google and GitHub, check the boxes next to the services you’d like to use, under External providers.
  4. Scroll down to Services > Git Gateway, and click Enable Git Gateway. This authenticates with your Git host and generates an API access token. In this case, we’re leaving the Roles field blank, which means any logged in user may access the CMS. For information on changing this, check the Netlify Identity documentation.

Celebrate!

Great job – you did it! Open your new page via the new Netlify URL, and navigate to /admin. If you did everything correct in the previous step, you should now be able to sign up for an account, and log in.

Tip: Signing up with an external provider is the easiest. If you want to sign up by email, you’ll have to set up a redirect in your index.js page (which we won’t be covering in this guide). For more information, have a look at the Add To Your Site section.

Congratulations – you can finally manage your new list of cats!