How YOU can use Gatsby, React and GraphQL to author blazingly fast static apps

Follow me on Twitter, happy to take your suggestions on topics or improvements /Chris

TLDR; This article is about learning what Gatsby is and what problems it solves.

At the beginning of the web it was all about documents and hyperlinks leading to other documents. We created these documents with the markup language HTML. Soon we got other things to enhance the experience namely CSS and JavaScript. Sites, in the beginning, were all static, files that one created and part of our site would never change. Then came AJAX and the ability to ask for content as part of user interaction or some other reason and the page could suddenly change from underneath us. The next revolution came with the arrival of SPA applications. SPA or Single Page Applications gave us the ability to create apps that would stay in one place. It would mimic having multiple pages through the use of JavaScript. Now we got web pages, that didn't make our pages flicker every time we navigated to a new page. In fact, we got apps that are fast and snappy just like client apps. All this speed comes at a price though.

These SPA applications came with some problems namely:

  • Slow loading, as they consisted of a lot of content that needed to be fetched from some endpoint and then rendered, they took time to render.
  • Less secure, compared to static pages that didn't have endpoints to call, SPA apps made heavy use of calls to the backend to both fetch and persist data. An endpoint is simply something that can be attacked and therefore needs to be protected.
  • Discoverability, the Web was built with static documents in mind. AJAX brought about a principle in which we could render a page on the client given a request for content to the backend and markup on the client. The page would only exist if a user actively went there. This principle meant that web crawlers belonging to search engines would be unable to index your page. Thereby anything you built with AJAX or SPA frameworks would not show up in search engine results.

This brings us to the present day where different innovations have been made to try to fix the above issues. To fix discoverability, different pre-rendering techniques have been invented to ensure our dynamic pages would exist when a web crawler came knockin. Another approach is using Static site generators. Static site generators are applications helping you author static content like HTML, CSS, and JavaScript. They have been around since the beginning of the web to make authoring documents a faster and more streamlined process. They have recently experienced an upswing in popularity, which brings us to Gatsby...

References

Here are some more links if you want to take your Gatsby app to the Cloud

The What and Why of Gatsby

Gatsby is a static site generation tool. It's a command-line tool that helps you create a static site. Gatsby is a static site generation tool built for the present day. What does that mean? It means today when we create a static site we want to create our pages based on markup and content. The content that we want can come from almost anywhere.

A static site generation tool today needs to be handle not only content existing in different formats such as XML, JSON, YAML, and more but also that content might need to be fetched from an endpoint for example. A tool like that needs to support a lot of file formats and ways of fetching content out of the box. Or it needs to be built in a way so that it can easily be extended to support the ever-changing landscape that is the Web and new file formats. Gatsby is both, it's able to support a lot of formats out of the box and fetching data using Web Requests. It also comes with a competent plugin system that enables you to easily add more functionality. Plugins can either be downloaded as modules you can author yourself and add them directly to your Gatsby project.

Gatsby Core technologies

What you author in Gatsby are components. When the components are put through a build process they turn into static HTML files. Gatsby's model consists of authoring components and pair them with content from a built-in data graph. How do we do that? Well, there are some core technologies that help us do just that namely:

  • React and React Router, what you author are components written in React.
  • GraphQL Gatsby also comes with a built-in data graph. This is an in-memory data graph that you can query using the query language GQL, GraphQL Query Language. GraphQL is normally used to negotiate with an API endpoint where you ask the API endpoint for exactly the data you need. In the context of Gatsby, GraphQL is used to query the in-memory data graph and provide that data as input to the components we author.

Our first Gatsby app

So how do you get started with Gatsby? You should have some things downloaded first like:

  • Git, you can install Git from here.
  • Node.js, to install Node.js please use nvm or grab an installer from this page.
  • gatsby-cli, the Gatsby CLI can be downloaded either by running npm install -g gatsby-cli or you can use npx and run it when you need it.

To create a Gatsby project type the following in a terminal:

gatsby new <project name>
1

Replace <project name> with an arbitrary name that you choose.

Now you should have a Gatsby project created.

Type the following to start up the development server and see your Gatsby project:

gatsby develop
1

Gatsby app in the browser

Next, we want to visit the in-memory data graph. Type the following address in your browser:

http://localhost:8000/___graphql
1

The built-in graph

Create a page with data

Now that we have a working Gatsby app up and running let's learn how to add some data to it. For this we will do two things:

  1. Create a page component
  2. Define and use a query targeting the built-in graph

Create page

In the directory src/pages, create a file about.js. Give it the following content:

import React from 'react';
import Layout from "../components/layout"

export default () => (
  <Layout>
    <div>About</div>
  </Layout>
)
1
2
3
4
5
6
7
8

Startup your development server with this command:

gatsby develop
1

Change the URL of your browser to http://localhost:8000/about, you should see the following being rendered:

Rendered about component

Define a query

Next, we will learn to use the built-in graph. Change your browser address to http://localhost:8000/___graphql. On your left drill down into the elements until you have the following selected:

Graphql element selection

In the middle section, you should now have the following query created for you.

query MyQuery {
  site {
    siteMetadata {
      author
      description
      title
    }
  }
}
1
2
3
4
5
6
7
8
9

Make a note of it by copying it to the clipboard.

Return to your about.js file and replace its content with the following:

import React from 'react';
import Layout from "../components/layout"
import { graphql } from 'gatsby';

export default ({ data }) => (
  <Layout>
    <h1>{data.site.siteMetadata.title}</h1>
    <div>{data.site.siteMetadata.description}</div>
    <div>{data.site.siteMetadata.author}</div>
  </Layout>
)

export const query = graphql `
 query {
  site {
    siteMetadata {
      author
      description
      title
    }
  }
}
`
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

The code above does the following. The query from the visual environment ended up at the bottom of the page. Then a new input parameter data was introduced to the component. data is assumed to contain the result of the query and the result is laid out in the markup part of the component. What happens here is that during build-time Gatsby will execute the query against the tree and input the result into your component.

DEMO json plugin

One of the most powerful things about Gatsby lies in its ability to use plugins to extend its capabilities even further. For this demo you will learn how to:

  1. Install and configure a plugin
  2. Create some JSON content
  3. Render JSON content that the plugin sourced into the built-in data graph.

Install the plugin

npm install gatsby-transformer-json
1

Create JSON content

Create the directory data under the src/ folder. In the data/ directory create the file products.json and give it the following content:

[{
  "id": 1,
  "name": "ngVikings"
},
{
  "id": 2,
  "name": "Microsoft Build"
}]
1
2
3
4
5
6
7
8

Configure the plugin

There are two things we always need to do when it comes to our content and getting it into the built-in graph.:

  1. Source the content, this process involves the fetching the data either locally or from a remote endpoint. Our content lives in a local file called products.json and we have a plugin that can help us source the content from it called gatsby-source-filesystem.
  2. Transform the content, once the plugin gatsby-source-filesystem has helped us source the content and create Nodes from all the JSON files we need to dig out the data from the JSON files, turned Nodes and augment the existing Nodes with that data.

Configure source plugin

Open up gatsby-config.js and in the plugins array add this entry:

{
  resolve: `gatsby-source-filesystem`,
  options: {
    name: `images`,
    path: `${__dirname}/src/data`,
  },
}
1
2
3
4
5
6
7

The above instruction is told to source the following directory ${__dirname}/src/data as instructed by setting the path property. This means our data/ directory where the JSON files live.

Configure transform plugin

All we need to do to configure this plugin is to ensure it's mentioned by name so Gatsby knows to invoke it. Add the following as an entry to the plugins array in gatsby-config.js:

`gatsby-transformer-json`
1

The configuration in gatsby-config.js should now look like this:

`gatsby-transformer-json`,
{
  resolve: `gatsby-source-filesystem`,
  options: {
    name: `images`,
    path: `${__dirname}/src/data`,
  },
}
1
2
3
4
5
6
7
8

Create page component with JSON data

Run the app with the command:

gatsby develop
1

In your browser navigate to http://localhost:8000/___graphql. Note how the JSON data has been sourced from the JSON file and put in the built-in graph:

GraphiQL JSON data

Above we have two new entries allProductsJson and productsJson. These two are slightly different. allProductsJson returns an array of JSON whereas productsJson returns one record back.

Drill down into the tree and select out properties. The constructed query should now look like the following:

Graphiql selected properties

Make a note of the query by copying it to the clipboard.

query MyQuery {
  allProductsJson {
    edges {
      node {
        name
        id
      }
    }
  }
}
1
2
3
4
5
6
7
8
9
10

Now create a file products.js under the pages/ directory and give it the following content.

import React from "react"
import Layout from "../components/layout"
import { graphql } from "gatsby"

export default ({ data }) => (
  <Layout>
    <h1>Products</h1>
    {data.allProductsJson.edges.map(edge => <div>{edge.node.id} {edge.node.name}</div>)}
  </Layout>
)

export const query = graphql`
  query {
    allProductsJson {
      edges {
        node {
          name
          id
        }
      }
    }
  }
`
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

Above we are adding the query we just made a note of. In the component we are laying out the response from the query like so:

{data.allProductsJson.edges.map(edge => <div>{edge.node.id} {edge.node.name}</div>)}
1

and it renders like so in the browser at http://localhost:8000/products:

Rendered products

Summary

In summary, you were taught some background on the history of the web and how static generators came about. You also learned how Gatsby addresses some problems with modern web development. Finally, you learned how to create and run a Gatsby app and also how to add different types of data to your app.