Building static websites with Gatsby and Contentful is not rocket science. Gatsby is a static page generator driven by React and GraphQL that your developers will love. If compared to WordPress, Gatsby provides access to modern JavaScript syntax and best practices for your developers to work with, which will definitely make them happier. It is also very simple to integrate any data source that can drive your pages like, for example, Cloudinary. Gatsby comes with a huge amount of addons that you can simply integrate into your page including Facebook Pixel, Mailchimp etc.
If you came across this article, you probably have been wondering if there is a better way to manage the content of your website (or blog) without having to code every time you want to add something new. The answer is - yes - just use Contentful.
In this article, I will show you how to create a module-driven blog using Gatsby and Contentful. Let’s start!
What is Contentful?
Let me give you a few words of introduction about Contentful. It is a nice headless CMS (Content Management System) where you can store assets and data to generate content of your pages. Contentful has one feature that we will utilize in this article - references and ways of managing them (which is actually very simple and flexible there).
It is super easy to integrate both tools to work together. Today I want to show how we can structure Contentful to use modular solutions that populate content of our page. We will create a simple Proof of Concept that will present this kind of approach.
1. Setup Project
First of all, we need to create a new organization
and create an empty space in it.
Now we need to create a GatsbyJS project using a starter given by Contentful.
Let’s setup a Gatsby project.
First, create an empty GitHub repository, for me, it will be placed here: https://github.com/tobob/blog
You need to have node environment setup, you can check this tutorial: https://www.gatsbyjs.com/docs/tutorial/part-zero/ if you don’t have it ready.
After installation we need to run in terminal:
$ yarn global add gatsby-cli@latest
Note: While writing this article Gatsby was in version 2.16.2.
then we create project:
$ gatsby new blog
https://github.com/contentful/starter-gatsby-blog
After some time we can follow with
$ cd blog
$ gatsby develop
it will throw an error:
Error: Contentful spaceId and the access token need to be provided.
So we need to set up our Contentful spaceId. Let’s run:
yarn setup
It will ask you about some tokens from Contentful:
To get them we need to check them on Contentful. Go into Settings > API keys
Under Content delivery / preview tokens should be already one entry (if not, you need to use the add button, it should be in the right corner).
Upon entering it, we can copy the 1st and 3rd value required by setup.
Starter will also ask about Content Management Token (2nd question). To populate Contentful with sample data and models, you need to go to Content management Token (one of the tabs) and click generate, then copy the token:
Just fill yarn setup with provided tokens/spaceId and let the magic happen.
Add one entry to .gitignore file
.env.*
It will prevent from committing our keys to GitHub.
Now! Let start Gatsby locally:
gatsby develop
You should see something like this:
and entering localhost:8000
should present
Easy, right? Let’s setup Netlify then.
2. Netlify
You need to have an organization profile (if you don’t, create an account, it should be easy). Then under ‘Sites’ you should see something like this - press New site from Git.
You can select your repository, but will need to choose a repository provider first and auth this service. I’m clicking the GitHub button and following the GitHub’s auth process.
After authorizing GitHub I was able to get a list of my repositories, so I am choosing tobob/blog
Woops! we didn’t push our code! Let’s enter your newly created repository and copy some command lines
Here we go!
Now, let’s go back to Netlify, we need to finish the process.
Nice! Let’s press ‘Deploy site’.
Damm! Something if off, the first build failed!
Let's check build blogs and here we go!
We don’t have a spaceId! Again!
This is just because the spaceId
that we have locally was not sent to GitHub (remember adding an entry to .gitignore?
). This is good behavior. We don’t want to send it there.
We need to set up some variables inside Netlify.
Let’s go to deploy settings and set up some variables:
You can check the .env. file to get values and keys quicker. Remember to save changes in Netlify.
Then trigger deploy again:
Just wait a bit, then you should see:
Upon clicking into green link you should see a deployed page.
3. Incremental Builds
Now let’s set up incremental builds.
You can follow: https://www.netlify.com/blog/2020/04/23/enable-gatsby-incremental-builds-on-netlify/
You can check changes in code here:
https://github.com/tobob/blog/commit/9c7a7b484306165dad53811e2a21ef0e5d08255c
After enabling cache we were able to reduce build time to 40s (from 2m 7s).
4. Webhooks from Contentful
Now we can set up build webhook by entering Contentful Settings > Webhooks and clicking Netlify Add in right panel
We also need to create build webhook in Netlify. Enter site settings and follow Build & Deploy searching for Build hooks
5. Creating models for page Components
Now we can start building our Proof of Concept. We need to specify the page model structure on Contentful first.
Let's create a few additional models definitions inside Contentful by entering the Model tab.
CodeComponent
- url - short text
QuoteComponent
- theme - short text
- quote - long text
- author - short text
WallOfTextComponent
- text - rich text
Those will be our block/modules that we will use to create blog pages.
Also, add additional field contentReferences into Blog Post model, reference type field - ‘many’.
We will keep references to components that we want to render on our page there.
So the goal here is to use references to structure page content. We need to now change the GraphQL queries to be able to fetch the page structure and pass it to some kind of component resolver.
Inside blog-post.js we have a query that is responsible for fetching blogs:
You can check this inside GraphQL panel that Gatsby provides.
Ok, let’s add our first reference to hello-world blog entry.
For example CodeComponent with sample gist URL.
Remember to publish the changes!
Let’s restart the Gatsby process to fetch the latest changes in Contentful model.
From Gatsby, we can get this information by using such query:
As you can see, I was able to get the info that under the given blog post we have one reference with ContentfulCodeComponent type. To get an URL that is nested within the ContentfulCodeComponent model we should extract this info from the given object.
For that, we will use such a construct:
Then, upon getting references, we will get a ContentfulCodeComponent object with an URL, splendid!
Let’s first create code-component.js inside components with the given content.
As you can see, inside the component file we also specified a Graphql fragment.
Now, we need to import CodeComponent into blog-post.js and destruct the given fragment in the main query.
Remember, you can check any changes in the code here:
https://github.com/tobob/blog/commit/7a712bb4a6ca7dfe8e4613c40d82edd7ced90b72
Now, we will add a method that will prioritize rendering references instead of the body inside BlogPost template.
Now we will add super-react-gist
yarn add super-react-gist
And finish writing the implementation of this CodeComponent.
Tada!
Now let’s add other components implementation:
and QuoteComponent
https://gist.github.com/tobob/da108275d8c51f1219f6fc7cce952041
We also need to make changes inside the blog component:
You can check full implementation here: https://github.com/tobob/blog/commit/3c3b4e38a7e269e2465aa0178ca2ac3e0a862e5d
We can also add more references inside our blog entry:
Remember to save!
You will probably need to restart the Gatsby server and check the results.
For me, it presents this variation:
We can now easily change order or content from Contentful.
As you can see, this is pretty awesome! You can check it out on https://condescending-ritchie-d18f95.netlify.app/blog/hello-world
However, this implementation has some limitations. It works perfectly when content is modular and order of the elements is the main respected factor of creating the design. With more complex designs, you will probably come across some issues.
Summary:
As you can see, writing an implementation for modular components with Gatsby and Contentful is pretty easy! It gives developers the ability to create reusable components that can be utilized by marketing guys with ease. I hope that my Proof of Concept will help you get comfortable with this concept.