Gatsby Tutorial Post Part 2: NetlifyCMS and Styling

This is the 2nd part of a tutorial series on building fast and elegant sites with Gatsby, Material-ui, and NetlifyCMS (part 1 here). The previous part of the tutorial showed how to setup Gatsby and create pages manually as well as dynamically using gatsby-node.js. This part of the series will show the following:

  • Creating the Courses Page and Individual Courses
  • Adding Images to the Courses/Posts
  • Install Material-UI plugins and style all pages with Material-UI
  • Installing NetlifyCMS to allow non-technical users to make content changes
  • Adding More Fields Types to the Courses (that work out of the box with NetlifyCMS)

Demo Site (Here’s where we’re going to get to)

Github Repo (If you’d like to jump right into the code)

Creating the Courses Page and Individual Courses

Our demo site features both blogs (which we did previously) and courses (which we’ll do now). Similar to the blogs, this involves creating a parent /courses page, a course template, a courseitem component (for the list on /courses, and the markdown files for the courses. So let’s first create the main /courses page (that will list all of the courses) and pages for each course.

Here’s how I created each of the pages:





/courses/ etc

What’s going on here? Let’s review:

Gatsby-node.js creates the course pages using the appropriate template with this section of the code:

In this case, it would be using single-course.js.

Within single-course.js there is a page query at the bottom. This queries for the right markdown file (using the id found in context) so that those specific pages will have the right title and html (from markdown) to display.

Within the courses.js file, we’re using a Static Query to query/search for the courses that have the templateKey of single-course and making a list of the courses (using the simple CourseItem.js component for help). This gives us a very basic (but functional) /courses page like this:

And an individual course page like this:

So these are pretty bland pages, unless you’re a hardcore minimalist. I’ll show you some Gatsby image plugins now that will add some color/life to these posts/courses.

Adding Images to the Courses/Posts

One of the top selling points of Gatsby is speed. Poorly sized or slow loading images are one of the easiest ways to make a website feel sluggish so this is an obvious area to optimize first. Two Gatsby plugins (gatsby-image and gatsby-transformer-sharp) are amazing tools for working with and optimizing Gatsby images. The latter leverages the Sharp image library, which is a very popular node module for resizing images. I’ll show you now to how add images to the course and post pages.

First, we need to install the plugins:

npm install --save gatsby-image gatsby-transformer-sharp gatsby-plugin-sharp

We’re also going to add a plugin that will allow us to access relative image paths in the project:

npm install gatsby-remark-relative-images --save

This will make for working with NetlifyCMS images easier later.

Then add them to the gatsby-config.js, within the big array of plugins like so:

Now we can add the images to our posts. Create a folder called /static and a folder within that call img. That’s where the images will live. I downloaded some demo images for this fake courses and put them in the folder.

Now within the individual course markdown files, we need to add the images within the frontmatter (—) headings like so:

Now, we’ll edit the single-course.js page to be able to query for this image and render it on the page. Change the GraphQL query at the bottom of the page to include the image query, like so:

This is using the gatsby-plugin-sharp plugin to render a fluid image with a maxWidth of 500 pixels. Right here within the GraphQL query, we’re able to choose how we’d like to receive the image in our component/html. This plugin has extensive documentation that can be found here.

Now, within the the single-course.js, we’ll use Gatsby-image to render the image in the html. It’s a simple import:

import Img from "gatsby-image"

And then a simple enough component to render.

<Img fixed={post.frontmatter.image.childImageSharp.fluid} />

This is how you add the right plugins, the files, and the queries to be able to use plugins within Gatsby.

Installing NetlifyCMS

NetlifyCMS (like an CMS) allows for non-technical users to edit content on a site. This allows people in marketing or content roles the freedom to create and frees up developers from having to do these sorts of small tasks. As was mentioned before, NetlifyCMS is made by static hosting service Netlify, but they can each be used separately from each other. Gatsby can be easily configured to work with WordPress, Contently, and many other data sources. NetlifyCMS has great docs, a generous free tier, and easy-to-use authentication.

NetlifyCMS is easy to configure with Gatsby using, you probably guessed it, gatsby-plugin-netlify-cms. Install it using npm and add it to gatsby-config.js:

npm install gatsby-plugin-netlify-cms --save

// gatsby-node.js

NetlifyCMS needs a config.yml file, which tells it which fields can be changed within the CMS. Create a folder called ‘admin’ within the Static folder and put the following config.yml file in it:

This creates 3 collections within the CMS: one for updating the about page, one for the courses, and one for the blogs. The ‘widgets’ are NetlifyCMS widgets and should be self-explanatory in a moment. With the above config.yml, this is what my admin interface looks like:

Within the Courses Collection, I see this:

Take a look, again, at the config.yml.

Notice how the fields with this file line up with what you’re seeing in the CMS image above? The template key is hidden so it doesn’t show. But right there are string widget (aka text field) for Title, Description, and Body. And there’s a datetime widget (a datepicker) for Publish Data. NetlifyCMS is really just an interface for making changes to our markdown files here. The config.yml serves as a way to tell Netlify which fields are available for editing. NetlifyCMS features a wide variety of default widgets and you can even make custom ones.


Although this takes some setup work, this workflow is extremely powerful for using Github markdown files as a CMS.

The final thing needed here is making the images hosted in static/img available for NetlifyCMS to use.

Add this to the top of the file within Gatsby-node.js

const { fmImagesToRelative } = require('gatsby-remark-relative-images')

And add this method call within the onCreateNode block:

exports.onCreateNode = ({ node, actions, getNode }) => {

const { createNodeField } = actions


This plugin was specifically built to make NetlifyCMS play nice with relative image paths. Failure to add this config right will send you to bug hell (e.g. “Field “image” must not have a selection since type “String” has no subfields.”)


Styling it all with Material-UI

We’ve built out our posts, blogs, and about page. Now we’ll see how to style out all of the pages using the most popular React UI framework, Material-ui. Material-ui has nearly 50,000 stars on Github and over 1,000 contributors. It is a React implementation of Google’s Material Design principles. Material-ui gives React developers a wide variety of components, styling, and utilities for making their sites aesthetically pleasing and easy to use. If you don’t want your site to look like a generic Googly app, Material-ui is supremely easy to customize to your liking.

There are many ways to add Material-ui to a Gatsby project. Material-ui has a Gatsby starter to use. Another developer made a dedicated Gatsby-starter with Material-ui. But I find the easiest way to add Material-ui to Gatsby is with gatsby-plugin-material-ui. The previous two work but they are much more complicated. Plugins are one of the awesome parts of Gatsby: Just install the plugin, add it to gatsby-config.js and you’re good to go. Here’s how to do just that:

npm install gatsby-plugin-material-ui @material-ui/styles

Edit gatsby-config.js

If you’ve worked with Material-ui before, you’ve probably played around with its theming capabilities. Material-ui themes allow you to establish a global theme that can be called from various child components. This makes it easier to create one coherent look and feel (vs. having pages/components with different styles, which can look sloppy). With the gatsby-plugin-material-ui plugin, this theme will go in that options object in the config above like so:

Now we can import material-ui components anywhere within the our Gatsby project. Here’s how I changed the single-course.js page:

Here’s how I changed the single-blog template:

Here’s the about page:

Here’s what I added to the home page to make it look a little more like appendTo:

And finally, here’s what I added to the NavBar to allow for navigating between the pages:

And here’s what we end up with:

We have here a site that we can continue to build upon and style with Material-ui. All users can make tweaks or changes using NetlifyCMS. And finally, this site is blazing fast and consists of static files that can be served for cloud storage service or CDN.

This starter project is a great way to start any project and I hope these two long posts helped you understand how it came together.

Recommended Reading

This tutorial showed you the essentials of Gatsby. That said, even with nearly 5500 words, it had to skip over a number of topics. Here’s some posts I recommend reading to get a better understanding of Gatsby:

Kyle Pennell
Kyle Pennell is a marketer and writer with a variety of technical chops (JavaScript, Google Sheets/Excel, WordPress, SEO). He loves clear and helpful copy and likes automating things and making web apps (mostly maps). Found at and many other digital spaces