Connecting Gridsome to NetlifyCMS

Step by step tutorial

Luca Spezzano
Jan 23, 2020 · 9 min read
Image for post
Image for post

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

Image for post
Image for post

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

Image for post
Image for post

and the page of the single article

Image for post
Image for post

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

Image for post
Image for post

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.

Image for post
Image for post

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

Image for post
Image for post

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

Image for post
Image for post

Click on Identity and after on the button Enable Identity.

Image for post
Image for post

Click Setting and usage

Image for post
Image for post

Under the Registration preferences select Invite only

Image for post
Image for post

Under the Services click the button Enable Git Gateway

Image for post
Image for post

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

Image for post
Image for post

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

Image for post
Image for post

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

NotOnlyCSS

This publication includes original articles and tips about…

Sign up for NotOnlyCSS

By NotOnlyCSS

Articles and tips for frontend developers Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Luca Spezzano

Written by

Frontend developer focused on CSS architecture of scalable and maintainable large scale projects and the development of amazing user interfaces.

NotOnlyCSS

This publication includes original articles and tips about frontend technologies.

Luca Spezzano

Written by

Frontend developer focused on CSS architecture of scalable and maintainable large scale projects and the development of amazing user interfaces.

NotOnlyCSS

This publication includes original articles and tips about frontend technologies.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store