Blog
-

Building the web of tomorrow with Gatsby

Reading time: ca.
4
minutes

If you're a content creator like me, you likely heard about the term CMS, which is short for Content Management System. These systems are all-in-one packages that allow you to focus on the content, while they focus on the other stuff necessary to get your content live and ready. Examples of these are storage, SEO, tagging, categorizing, theming, uploading media, rendering and so on. Famous examples are WordPress, Drupal and Joomla.

These systems all work in a very similar way, as a content creator, you log in, write your content, and save it. The CMS will then store your content within a database. When an end-user visits your website, the CMS will fetch your content from the database. Then it applies some plugins and themes to render a complete HTML page.

This type of flow is what we call Server-Side Rendering. While this works great, the work that the CMS has to do still costs some time. This also means that if a second user visits the same webpage, the CMS has to execute the same process to end up with the same HTML page. Typically, we solve this problem by caching. Caching means that we save the result HTML page somewhere (either on the filesystem, or within the same database as the content). When an end-user visits the webpage, the CMS will first check if it has a cached version, and will return that in stead.

You could ask yourself, if this is the right solution. What if, we write our content, and the moment we "save" the content, all the HTML pages are generated, and published immediately. That means that if an end-user visits our website, he no longer has to wait for the CMS to finish doing its work, and we could immediately retrieve the HTML. In this case, we're no longer relying on the CMS to visualize or to render the content, and thus, we're no longer depending on the plugins or themes provided by the CMS. In stead of that, we use a tool that compiles the content into HTML, which we call a Static Site Generator. These static site generators completely decouple content from the way it's being rendered. This allows you to switch from one static site generator to another, without having to convert your content.

Meet Gatsby

There are many static site generators available, written in most programming languages, such as Jekyll (Ruby), Hugo (Go). Additionally, you have several options in the JavaScript ecosystem as well, and one of my personal favourites is Gatsby, which is built upon React and GraphQL.

The reason why Gatsby is one of my favourite static site generators is because its built upon modern web technologies such as GraphQL and React. Additionally, it comes with a rich ecosystem with several integrations, which allow you to bring your content from anywhere. Regardless of whether you're using a JSON file, a CMS, Markdown files or some other API, you can import it with Gatsby. Gatsby will expose your content as a GraphQL API, which you can use within your React components. When you publish a new post, you can start the Gatsby CLI to generate static assets.

And even though you're generating static assets, Gatsby also completely hydrates back to a fully-fledged React application. Another benefit of Gatsby is that it's all JavaScript, you don't need to learn another programming language to extend the system. Rather than that, you can use one of the many available JavaScript hooks to extend the system. The last benefit I want to talk about is performance. As the Gatsby website says, it helps you build "blazing fast websites and apps". You don't have to believe my by my word though, with Gatsby I managed to reduce the time for a First Meaningful Paint from 3.9 seconds to 0.9 seconds. While three seconds may seem to make no difference, be aware that according to Pinterest, a 40% decrease in loading time caused a 15% increase in SEO traffic (Source), and at BBC they noticed that for every second it takes to load, 10% of their users leave (Source).

Headless CMS and the JAMstack

Since we decoupled the content from rendering it, it also introduced us to a wide range of Content Management Systems that are only used for managing the content, which we call a headless CMS. They usually provide an API that can be used to fetch the content from, and which integrates seamlessly with Gatsby. Examples of these are the Netlify CMS, Sanity.io, Contentful and Forestry.

There's also a name for a stack like this, and this is the JAMStack, which stands for:

  • JavaScript (eg. React)
  • APIs (eg. a headless CMS)
  • Prerendered Markup (eg. a static site generator)

Getting started with Gatsby

To start a new project with Gatsby, we need to install the Gatsby CLI and use it to create a new project:

npm install -g gatsby-cli
gatsby new hello-world-gatsby

You can also use one of the more than 300 other starters to generate a specific project, but in this case, we'll stick to the default starter. As a simple project, I'm going to use a JSON file as an input. Since I love the Google Graveyard project, I'll take their JSON file to get started. First, we have to make Gatsby JSON-aware by installing a separate module:

npm install gatsby-transformer-json --save

After that, we can add some configuration to our project to read the JSON file:

{
resolve: `gatsby-source-filesystem`,
options: {
name: `graveyard`,
path: `${__dirname}/src/data/`,
plugins: [
`gatsby-transformer-json`
]
}
}

If we start the application now, and open GraphiQL (by default available at http://localhost:8000/__graphql), we have a allGraveyardJson and a graveyardJson operation.

Using this operation, we can write a query to fetch all entries within the JSON file, such as:

query {
allGraveyardJson(sort: {fields: dateClose, order: DESC}) {
edges {
node {
name
closed: dateClose(formatString: "YYYY")
opened: dateOpen(formatString: "YYYY")
closedAgo: dateClose(fromNow: true)
description
}
}
}
}

With Gatsby, you can now use this query within a React page component, using the useStaticQuery() React hook:

const {allGraveyardJson} = useStaticQuery(graphql`
query {
allGraveyardJson(sort: {fields: dateClose, order: DESC}) {
edges {
node {
name
closed: dateClose(formatString: "YYYY")
opened: dateOpen(formatString: "YYYY")
closedAgo: dateClose(fromNow: true)
description
}
}
}
}
`);

Using that data, you can build an entire React application.

The nice thing about Gatsby is that you don't have to use JSON. Do you want to use Markdown? There's a plugin for that. Heck, there's even a plugin to use Markdown with JSX. Are you an influencer on Instagram, well, you can add all your images to your Gatsby site as well. Do you prefer writing in WordPress? Well, Gatsby can do that too. Even if all those other options don't work, but your site has an API, you can still use Gatsby!

Using this operation, we can write a query to fetch all entries within the JSON file, such as:

query {
allGraveyardJson(sort: {fields: dateClose, order: DESC}) {
edges {
node {
name
closed: dateClose(formatString: "YYYY")
opened: dateOpen(formatString: "YYYY")
closedAgo: dateClose(fromNow: true)
description
}
}
}
}

With Gatsby, you can now use this query within a React page component, using the useStaticQuery() React hook:

const {allGraveyardJson} = useStaticQuery(graphql`
query {
allGraveyardJson(sort: {fields: dateClose, order: DESC}) {
edges {
node {
name
closed: dateClose(formatString: "YYYY")
opened: dateOpen(formatString: "YYYY")
closedAgo: dateClose(fromNow: true)
description
}
}
}
}
`);

Using that data, you can build an entire React application.

The nice thing about Gatsby is that you don't have to use JSON. Do you want to use Markdown? There's a plugin for that. Heck, there's even a plugin to use Markdown with JSX. Are you an influencer on Instagram, well, you can add all your images to your Gatsby site as well. Do you prefer writing in WordPress? Well, Gatsby can do that too. Even if all those other options don't work, but your site has an API, you can still use Gatsby!

Lessons learned

While developing with Gatsby, I also encountered a few things, which might be useful to know when starting with Gatsby. First of all, when running gatsby develop, things might behave different in comparison to using gatsby build. For example, if you use browser APIs like the LocalStorage API in a React component, you'll notice that this fails when building. Always check if things are working when doing a production build.

Another thing I noticed is that many resources that work with Markdown/Remark, won't necessarily work with WordPress. For example, lazy-loading images or syntax highlighting requires a completely different setup when working with WordPress.

Like what you see here? Check out more like this through the rest of our blogs.

Dimitri Mestdagh

February 8, 2022

Read the highlights of our blog

"Each project pushes our skills farther and expands our expertise"

Let's talk!

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
We value your privacy! We use cookies to enhance your browsing experience and analyse our traffic.
By clicking "Accept All", you consent to our use of cookies.