Connecting Gridsome to NetlifyCMS
Step by step tutorial

For the last past months, I have been searching for a Headless CMS to connect with a modern Javascript framework like Vue.js to use for my clients.
After a long search, I found the perfect combination for my needs thanks to a static site generator like Gridsome and a headless CMS like NetlifyCMS.
Static site generators have become very popular because they are straightforward to use, and they are based on JavaScript frameworks like Vue.js or React.
A static site generator uses plain text files rather than a database as the content repository and builds HTML files by applying layouts to them.
The generated static site files(HTML, CSS, JS) are delivered to the end-user exactly as they are on the server. There is no server-side language or database.
Headless CMS make easy to access content via RESTful API.
A headless content management system, or headless CMS, is a back-end only content management system (CMS) built from the ground up as a content repository that makes content accessible via a RESTful API for display on any device.
These create a new architectural concept also called JAMstack, which I talk about more in this article, I recommend you read it to be able to better understand the topic we’re going to deal with today.
Today we will use the JAMstack architecture by connecting Gridsome to NetlifyCMS.
What are we going to develop?
We will develop a simple blog with a list of articles and the specific page of the article, to show the basic functions and how to connect the two technologies step by step.
Then it’s up to you to discover all the features.
Requirements
- Basic JS knowledge
- Basic VueJS knowledge
- Basic GraphQL knowledge would be nice (but not necessary)
- Set up a repository on Github for this project
- Having a Netlify account
Step 1 — Install Gridsome CLI tool
yarn global add @gridsome/cli
or
npm install --global @gridsome/cli
I will be using yarn during this tutorial.
Step 2 — Create a Gridsome project
gridsome create my-blog
once created we need to open the folder so
cd my-blog
now if you want to start a local dev server
gridsome develop
Ps. Now initialize your repo on Github.
Step 3 — Install Gridsome plugins
For our project, we will need two plugins: transformer-remark and source-filesystem.
- source-filesystem: it transforms files into content that can be fetched with GraphQL in your components;
- transformer-remark: it parses and compiles Markdown;
yarn add @gridsome/transformer-remark
and after
yarn add @gridsome/source-filesystem
Step 4 — Setting up the Gridsome config file
As you may have noticed in our folder, there is a file gridsome.config.js
, here let’s add this code
module.exports = {
siteName: 'My blog',
plugins: [
{
use: '@gridsome/source-filesystem',
options: {
path: 'articles/**/*.md',
typeName: 'Articles',
remark: {}
}
},
],
transformers: {
remark: {}
}
}
with thepath
we say where to look for files and with typeName
we decide the GraphQL type and template name.
Step 5 — Create a Markdown file
At the same level as the gridsome.config.js
file create a folder called articles
and inside it let’s create a file called my-first-article.md
.
Now in your my-first-article.md
file add this
---
title: My First Article
image: https://source.unsplash.com/random/1
abstract: |-
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
author: Mario Rossi
date: 2020-01-07T17:43:37.669Z
---Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Do the same for the second article! (just change the number after random to get a different image)
Ps. be careful with the indentation of the code in this file because it is easy to get an error.
Should look like this

Step 6 — Get the list of articles
Now let’s try to render our articles in the home, but before let’s clean the Default file and inside src/layouts/Default.vue
remove everything and add this code
<template>
<div class="layout">
<slot/>
</div>
</template><static-query>
query {
metadata {
siteName
}
}
</static-query><style>
body{
background-color: #f4f4f4;
padding: 0;
margin: 0;
}@media screen and (min-width: 992px) {
.container {
width: 60%;
margin: 0 auto;
padding: 30px 0px;
}
}
</style>
Now let’s go Inside src/pages/Index.vue
and let’s write
<template>
<Layout>
<div class="container">
<h1>List articles</h1>
<div v-for="article in $page.articles.edges" :key="article.id" class="article d-flex">
<div class="article__img"
:style="{ 'background-image': 'url(' + article.node.image + ')' }"></div>
<div class="article__body">
<g-link :to="article.node.path" class="article__link"></g-link>
<h1 class="article__title">{{article.node.title}}</h1>
<p class="article__abstract">{{article.node.abstract}}</p>
</div>
</div>
</div>
</Layout>
</template><page-query>
query {
articles: allArticles {
edges {
node {
title
abstract
image
path
}
}
}
}
</page-query><script>
export default {
metaInfo: {
title: "My blog"
}
};
</script><style>
.article {
display: flex;
align-items: center;
box-shadow: 5px 5px 11px rgba(0, 0, 0, 0.15);
border-radius: 8px;
position: relative;
margin-top: 50px;
background-color: #fff;
}
@media screen and (max-width: 992px) {
.article {
display: block;
}
}
.article__title {
margin-top: 0;
}
.article__body {
padding: 15px 30px;
}
.article__link {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
}
.article__img {
width: 250px;
height: 140px;
background-size: cover;
background-position: center;
border-radius: 8px;
margin-right: 15px;
}@media screen and (max-width: 992px) {
.article__img {
width: 100%;
height: 180px;
}
}
</style>
Step 7 — Create the layout for the page for the single article
Go inside the folder src/templates
and create a file Articles.vue
and inside src/templates/Articles.vue
let’s write
<template>
<Layout>
<div class="articlePage">
<div class="articlePage__img"
:style="{ 'background-image': 'url(' + $page.article.image + ')' }"></div>
<div class="container container--article">
<g-link to="/" class="back"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="arrow-left" class="svg-inline--fa fa-arrow-left fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M257.5 445.1l-22.2 22.2c-9.4 9.4-24.6 9.4-33.9 0L7 273c-9.4-9.4-9.4-24.6 0-33.9L201.4 44.7c9.4-9.4 24.6-9.4 33.9 0l22.2 22.2c9.5 9.5 9.3 25-.4 34.3L136.6 216H424c13.3 0 24 10.7 24 24v32c0 13.3-10.7 24-24 24H136.6l120.5 114.8c9.8 9.3 10 24.8.4 34.3z"></path></svg>Back</g-link>
<h1 class="articlePage__title">{{$page.article.title}}</h1>
<p>{{$page.article.author}}</p>
<p>{{$page.article.date}}</p>
<div v-html="$page.article.content"></div>
</div>
</div>
</Layout>
</template><page-query>
query ($path: String!) {
article: articles (path: $path) {
title
content
author
image
}
}
</page-query><script>
export default {
components: {},
metaInfo() {
return {
title: this.$page.article.title
};
}
};
</script><style>
.container--article {
margin-top: -140px;
background-color: #fff;
border-radius: 8px;
padding: 30px 60px;
margin-bottom: 100px;
}
@media screen and (max-width: 992px) {
.container--article {
padding: 15px 20px;
}
}
.articlePage__img {
width: 100%;
height: 400px;
background-size: cover;
background-position: center;
}
.back {
display: flex;
align-items: center;
color: #333;
text-decoration: none;
}
.svg-inline--fa{
width: 20px;
margin-right: 15px;
color: #333;
}
</style>
If you’ve come this far, you’re doing great, and now you should see the home page with the list of the articles if you run in the terminal gridsome develop

and the page of the single article

Well, this is a lot so far, and we did the most challenging part now we need to set up Netlify CMS and to connect it.
For the next steps, we are going to follow the documentation of NetlifyCMS.
Step 8 — Add NetlifyCMS to our blog

Inside our static
folder we need to create a folder admin
with two files: index.html
and config.yml
The index.html
is the entry point for the Netlify CMS admin interface. This means that the users navigate to yoursite.com/admin/
to access it.
Inside it let’s write
<!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>
<script src="https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js"></script>
</body></html>
The config.yml
defines the backend configurations like the repository options, the folder for the images, the collections for instance.
Inside it let’s add
backend:
name: git-gateway
branch: master # Branch to update (optional; defaults to master)media_folder: "static/uploads"
public_folder: "/uploads"collections:
- name: "articles"
label: "Article"
folder: "articles"
create: true
slug: "{{slug}}"
fields:
- {label: "Title", name: "title", widget: "string"}
- {label: "Abstract", name: "abstract", widget: "text"}
- {label: "Image", name: "image", widget: "image"}
- {label: "Author", name: "author", widget: "string"}
- {label: "Date", name: "date", widget: "datetime"}
- {label: "Body", name: "body", widget: "markdown"}
Ps. Be careful with the indentation and the spaces of the code in this file because it is easy to get an error. The spaces in your code must be exactly like the example above.
Step 9 — Override the index.html with Gridsome
We need to override the base HTML template to add some script required by Netlify CMS, Gridsome has a feature for this and it is called Overriding Index.html.
Now inside the src
folder create a file index.html
and let’s add this code
<!DOCTYPE html>
<html ${htmlAttrs}>
<head>
${head}
<script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>
</head>
<body ${bodyAttrs}>
${app}
${scripts}
<script>
if (window.netlifyIdentity) {
window.netlifyIdentity.on("init", user => {
if (!user) {
window.netlifyIdentity.on("login", () => {
document.location.href = "/admin/";
});
}
});
}
</script>
</body>
</html>
Now everything is ready, and it’s time to push all the work we have done on Github.
Step 9 — Configuration on netlify.com
Go on the Netlify website and do the Signup/Login, once you are inside your dashboard you should see this
Click the button New site from Git, from here you will authorize Netlify to connect to your Github repository.

Click on Github and do the necessary steps to associate a specific repository

Now write gridsome build
as Build command and dist
as Publish directory and click Deploy Site (wait until it will be deployed).

Click on Identity and after on the button Enable Identity.

Click Setting and usage

Under the Registration preferences select Invite only

Under the Services click the button Enable Git Gateway

Go back to the Identity tab and click the button Invite users, to allow somebody to edit content from the admin section.

Add your email address and you will receive an email, you need to accept the invite, you will choose a password, and now from your-url.com/admin you will be able to Log in, and you will be able to change the content of your blog.
You should see your Netlify CMS like this

Try to create an article or modify an existing one, wait for the deployment and voila your changes will be online.
Now every time you will change something, Netlify automatically will push on Github and will do the deploy.
This is just a starting point, what we have done for the articles obviously can be replicated for anything: projects pages etc.
Now it’s up to you to have fun and create your projects from this code.
You can find the code here on Github, and if you want to take a look at the demo of this tutorial click here.
If you want to know more about these technologies I suggest you look at the Netlify CMS documentation and the Gridsome documentation