Published on April 13, 2018
Many of us love static sites for their simplicity: they are cheap to deploy and maintain, and also incredibly quick to load. When Gatsby appeared, it even became possible to create hybrid sites using React, which are rendered statically but become interactive once loaded client-side.
You just write some GraphQL, pass the data to your UI components, and the rest is done for you.
"What if we took a static site, and made it more dynamic?" â Stephan
I laughed at first, shook my head, but then started thinking. What first seemed like a silly contradiction slowly started to make sense to me.
GatsbyJS offers a full-fledged static content authoring experience that allows connection of your projects to many APIs and data sources, including Contentfulâs content infrastructure, making it an excellent companion to Gatsby. With Contentful being a first-class citizen in the Gatsby world, content is easily edited in a nice UI and with the use of Netlify, setting deployments up takes less than a minute.
The only benefit classic dynamic websites offer over these new workflows is that content can be edited right on the page â you click âeditâ, make your changes, and you are done.
Thus, we set out to try and solve this using the Contentful delivery and especially the powerful management APIs, some GraphQL and a few terribly styled React components.
If you are curious about static sites, Gatsby, Gatsby plugin development or new ideas on how to use Content Infrastructure, then this post is for you.
There is a template with source files available on Github; this will come in handy as reference in later parts of this article.
What weâre going to do first is set up a static site that is automatically deployed to Netlify. Letâs begin by using a starting template. Go ahead and click "Fork" in the upper right corner of the repo to make your own copy to work on.
After that, clone the project.
cd
into the directory and run npm install
While npm
is doing its thing, use the time to sign up for a free Contentful account â you can make it even easier and sign in using your Github account with one click.
Once youâre in, choose to create an empty space.
Now in the gatsby-starter-gcn
folder, run npm run setup
and follow the instructions.
It will bootstrap all the data that is needed for the example to run using the Contentful Import tooling, which in turn uses the Management API, the same thing we will be using later to actually update the content using our plugin.
After that is done, you can run npm run dev
and go to http://localhost:8000 to see your fresh new static site.
Next follow these deployment instructions, and optionally some additional settings, to get your website fully set up and accessible on the Internet. Now, every time you push some code or edit content, your site is automatically rebuilt.
To recap our initial plan: We want to allow developers to easily mark parts of the static site as loaded from a specific Contentful entity and then show an âEditâ link on the generated site. That allows any admin user with a Management Token to edit the content right on the website; with the updated content automatically showing up on the site after a while.
If youâve followed Part I, that last part would already be taken care of â whenever you push code or publish an entity on Contentful, Netlify will rebuild your site and distribute it on its content delivery network (CDN).
Before we dive into the implementation details, letâs do a quick refresher on how Gatsby renders static sites:
In Gatsby, you define a âPageâ type and the GraphQL query, for all the data needed to render a page inline with the âPageâ component.
During the build stage, before rendering the component, that data is fetched from a âSourceâ and then later provided to the component for rendering.
Contentful provides a source plugin for that out-of-the-box.
Gatsby also provides an extension API that allows you to hook into almost every step of the build process and customize things.
Letâs take a look at src/pages/index.js
: The query requests allContentfulPost
, yielding a list of all entries for the Post
content type. From there, it selects a set of properties that it needs to render.
In order to build an editing component, in addition to the actual content, we need to know the associated content model in Contentful so that we can render an interface to edit the content.
Hereâs the query weâd like to use:
This little addition tells the internal GraphQL endpoint that we would like to have a contentfulEditor
object that contains the Content Type ID, Entity ID, Space ID, and the id and type of all the fields.
"Thatâs great, Tim, but so far thatâs nothing but wishful thinking", I hear you say.
That is true, but having specified our interface now, it will be much easier to know exactly what we need to implement. So letâs jump to that.
As mentioned earlier, Gatsby allows you to hook into almost every build step. What we would like to do is hook into a point where the data has already been loaded, then add some additional data about the content model on top of it.
The âsetFieldsOnGraphQLNodeTypeâ extension point is the perfect candidate for that. It allows you to change the data from the GraphQL query, before any pages were rendered, but after the Contentful source plugin has already fetched the data.
First, we create a folder âpluginsâ in the project root â Gatsby will automatically look through any folders in the âpluginsâ directory, so letâs create a folder named âcontentful-editorâ inside of that.
Within âcontentful-editorâ, create a package.json
file containing just â{}â (Gatsby infers the plugin name from the folder structure) and a gatsby-node.js
file. That tells Gatsby to register an extension to run for every node
; meaning it will be called for every Page that you are about to define.
In there, we will want to do the following:
If a node contains data fetched from Contentful, collect all the entities in it and query the API for them
Query the Contentful API for all the Content Types that are associated with those entity
Append the previously defined data to every data node
Hereâs what it will look like:
You can find the complete code in the gatsby-node.js file on Github.
Now, we have all the data available, we can move on to rendering an inline editor.
Letâs once again do a quick recap on what weâve done so far:
Set up your own gatsby example project on Github
Your example project is automatically deployed to netlify on any content changes or code changes
When rendering a page, we can now query for the metadata about the underlying content model for a page
Whatâs left to do:
We need to build a React component that can wrap any other React components that use data from Contentful
Letâs take another look at âsrc/pages/index.jsâ (also available as reference on Github): The CardList
component iterates over all the posts from Contentful and renders a Card
component from every Contentful âPostâ.
This is the ideal point where we can introduce our wrapper component that enables on-page editing. We wrap it with a âContentfulEditorâ component and pass the ID, âcontentfulEditorâ data and the post content to it:
Then, we proceed with creating a new file /src/components/ContentfulEditor.js
In there, we want to wrap the âCardâ so an âEditâ button is shown on top of it. When that is clicked, a modal that renders an interface to edit content opens; that syncs any changes back to Contentful via the API. That in turn triggers a rebuild on Netlify, updating the actual site after a while.
When we click on the edit button, we open a modal with the editor. Inside of the editor, we extract the field data and, based on the type of a field, render an editor. This is done by the following code:
When âsaveâ is clicked, the following code uses the management SDK to upload the data to Contentful:
Now, just push your changes to Github, wait for Netlify to finish with the new build and youâre ready to go.
Contrary to popular belief, static sites actually can be made dynamic by using Contentfulâs Content Management APIâs â thatâs a major benefit of using a Content Infrastructure over a traditional CMS. Imagine implementing a chatbot that allows you to update your static site via a simple chat message, or the ability to integrate your website with Amazon Alexa and update it with just voice interfaces â your imagination is the only limit as to where and how you can interact with your content.
Want to do more with Gatsby and Contentful? Get started here.
Subscribe for updates
Build better digital experiences with Contentful updates direct to your inbox.