How to Implement Netlify CMS With Next.js

Manage the content of your Next.js apps through a free Git-based CMS

If you’re starting a new React project, you might want to consider Next.js and Netlify CMS. In this article, we take a look at why this would be a great choice and walk through the process of setting up a new project using these technologies.

Why Next.js?

As I stated in a previous article:

“There are many important details you need to consider when you start a new project with React. Your code has to be bundled using a bundler like webpack and transformed using a compiler like Babel.

Create React App can be a nice tool to handle this for you and give you a massive head start, but what about code-splitting, pre-rendering for performance, and SEO or server-side rendering?

To build a complete React application, you need more than CRA provides you with. You can save yourself some time by using Next.js, a React framework that provides a solution to all of these problems.”

If you want to read more about CRA vs. Next.js, check out Stack choices: Create React App vs Next.js.

Why Netlify CMS?

Netlify CMS is an open-source Git-based content management system. It is based on client-side JavaScript and handles content updates directly in Git. Because all content is just stored in your Git repository, you don’t need to have anything hosted on a server. It’s completely free and a great fit to combine with Next.js to build landing pages or blogs that are manageable through a nice UI.

Let’s Begin

Let’s begin building our landing page with some basic text to get familiar with Netlify CMS. You can find the source code of this part of the tutorial on GitHub or check out serverless.page for a complete boilerplate that also includes features like authentication and billing.

Set up your project

You can start by creating a new Next.js project with npx create-next-app. In this example, we are going to use TypeScript. You can follow this tutorial on how to set up Next.js with Typescript.

Using Markdown Files for Our Content

Netlify CMS works with markdown files, and it’s a great way to manage the content of your landing page or blog. Let’s begin by creating a markdown file that will have some data we want to show on our home screen.

Make a content directory that will hold all our markdown files. Next, create a pages directory and a markdown file called content/pages/home.md. This file will hold the data that we want to show on our home page. Let’s start by adding a title, description, and image for the “hero” section of our landing page:

---
hero_title: Build a SaaS faster with React
hero_description: Serverless SaaS is aiming to be the perfect starting point for your next React app to build full-stack SaaS applications. Visit serverless.page for more info.
---

Next, we need to tell webpack how to load markdown files. Let’s use frontmatter-markdown-loader for this. Start by installing that package as a dev dependency:

yarn add frontmatter-markdown-loader -D

Next, create a new next.config.js file at the root of your project with the following content:

Create the home page

Cool, now let’s add some code to the index page to make it our home page.

In pages/index.tsx, add the following:

Let’s have a look at what’s going on here. The most important part is the exported getStaticProps function. If you export an async function called getStaticProps from a page, Next.js will pre-render this page at build time using the props returned by getStaticProps.

On our page, we import our markdown file called home.md and pass it a content prop to our component. Our home page can now use the hero_title and hero_description attributes of the markdown file.

Let’s try it out and see if it’s working:

yarn dev

You should see your amazing hero section, ready to be styled and managed with your upcoming CMS.

Implement Netlify CMS

There are different ways to add Netlify CMS to your project. We are going to use the official npm package:

yarn add netlify-cms-app

Add the configuration

Before we can initialize our CMS, we need to create a config file. Create a cms directory at the root of your project and paste the following configuration to your cms/config.js:

export default {
  cms_manual_init: true,
  backend: {
    name: 'github',
    repo: 'yourname/your-github-repo-name',
    branch: 'main',
  },
  media_folder: 'public/img',
  public_folder: 'img',
  collections: [
    {
      name: 'pages',
      label: 'Pages',
      files: [
        {
          label: 'Home',
          name: 'home',
          file: 'content/pages/home.md',
          fields: [
            {
              label: 'Hero Title',
              name: 'hero_title',
              widget: 'string',
            },
            {
              label: 'Hero Description',
              name: 'hero_description',
              widget: 'markdown',
            },
          ],
        },
      ],
    },
  ],
};

Netlify CMS has different options on how to handle authentication. We are going to use this config file to tell Netlify CMS that we want to use the GitHub for this. For repositories stored on GitHub, the github back end allows CMS users to log in directly with their GitHub account. Note that all users must have push access to their content repository for this to work.

If you haven’t done already, now would be a good time to create your repository on GitHub, add the name of your repo to the config file, and push your code to GitHub. Go ahead — I’ll wait.

Good, but before we move on, let’s take a look at the most important setting of our configuration: the collections. This determines how content types and editor fields in the UI generate files and content in your repository.

Inside collections, we create a pages collection that has some settings for the home page. For now, we only added the hero_title and hero_description fields. You can set which widget to use for the given property.

You can read about all other configuration options in the documentation.

Initialize the CMS

Next, let’s create an admin page for our CMS. Add the following code to pages/admin.tsx:

import dynamic from 'next/dynamic';
import config from '../cms/config';

const CMS = dynamic(
  () =>
    import('netlify-cms-app').then((cms) => {
      cms.init({ config });
    }),
  { ssr: false, loading: () => <p>Loading...</p> }
);

const AdminPage: React.FC = () => {
  return <CMS />;
};

export default AdminPage;

Now you should be able to navigate to http://localhost:3000/admin and see a GitHub login button. Hit the button and see your nice new CMS!

Blank CMS

Try it out

Cool, now try it out! Select “Home” and you will see the edit page. You can edit the hero_title and hero_description properties and click the publish button. When you publish, Netlify CMS is making a commit to your repository with the changes you just made. You can take a look at the last commit after you have published some changes.

Now, all you have to do is git pull to get those changes locally and navigate back to http://localhost:3000/. You will see that the home page contains your changes. Sweet!

Adding Images

Most hero sections contain a pretty image. Let’s use the image widget to add an image to our hero section. Go to your cms/config.js file and add the following object to the fields array:

{
  label: 'Hero Image',
  name: 'hero_image',
  widget: 'image'
}

Next, we could simply add an image to our public/img folder and add it to our home.md, but to demonstrate how Netlify CMS works, we are going to use the CMS to do it.

First, we need to upload an image to our integrated media library. On the dashboard of the CMS, click the “Media” link in the top navbar and upload an image. After that, navigate to the edit screen of the home page.

You should now see the added hero_image field with a button that says, “Choose an image.” You can now select your uploaded image and publish the changes.

Great, we should now have a new commit to our repo with the new changes. If our application was already in production, we could see the changes live, but since we want to see these changes locally, we need to first pull them from GitHub.

After you have run git pull, there is really only one thing left to do, which is adding the image to our home page:

...
<img src={attributes.hero_image} alt='hero image' />
...

Now, run yarn dev and go to http://localhost:3000/ to see your added image!

Conclusion

Netlify CMS is a very useful library you can add to your Next.js apps. It’s just a client-side React application, and it uses Git to store content in your own repository. This has some nice benefits: You don’t need to host your CMS separately and it fits perfectly in your Git workflow. This is great for managing the content of a landing page or blog post.

If you are looking for a complete boilerplate, check out serverless.page.

Next Steps

We have covered a lot in this tutorial, but we have only seen the basics of how Netlify CMS works in a Next.js application. There is a lot more we can do! Stay tuned for upcoming articles to continue our work with:

  • A blog
  • More widgets for managing content
  • Styling and CMS previews
  • Customizing with additional configuration settings

View the source code of this tutorial on GitHub.

Thanks for reading!

Building a SaaS?Give yourself a head start.

Serverless SaaS is aiming to be the perfect starting point for your next React app. Start with a boilerplate that includes a landing page, authentication, billing, teams, a blog and more.

Learn more