How YOU can use Gatsby, React and GraphQL to author blazingly fast static apps
Tags: gatsby, react, tutorial, javascript
Published: 2020-07-01 13:35:44

---
title: How YOU can use Gatsby, React and GraphQL to author blazingly fast static apps
published: true
description: This article teaches you how to use Gatsby and GraphQL to create static web sites
tags: gatsby, react, tutorial, javascript
series: Gatsby
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/8x4ruc5f1hk4enp6dnzg.gif
---

Follow me on [Twitter](https://twitter.com/chris_noring), 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

- [Gatsby docs](https://www.gatsbyjs.org/docs/quick-start/)
Gatsby's official docs.
- [Gatsby tutorials](https://www.gatsbyjs.org/tutorial/)
A really good set of tutorials that will take you from your first steps with Gatsby to.
- [Gatsby CLI tool I built](https://github.com/softchris/gatsby-cli)
This CLI tool helps you scaffold, components, pages, and plugins.

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

- [Docs: Azure Static Web Apps, overview page](https://docs.microsoft.com/en-gb/azure/static-web-apps?WT.mc_id=staticwebapps-github-chnoring)
- [Docs: Azure Static Web Apps, add Serverless API](https://docs.microsoft.com/en-us/azure/static-apps/apis?WT.mc_id=staticwebapps-github-chnoring)
- [Docs: Azure Static Web Apps, setup Custom domain](https://docs.microsoft.com/en-us/azure/static-apps/custom-domain?WT.mc_id=staticwebapps-github-chnoring)
- [LEARN module: Gatsby and Azure Static Web Apps](https://docs.microsoft.com/learn/modules/create-deploy-static-webapp-gatsby-app-service?WT.mc_id=staticwebapps-github-chnoring)
- [LEARN module: SPA applications + Serverless API and Azure Static Web Apps](https://docs.microsoft.com/learn/modules/publish-app-service-static-web-app-api?WT.mc_id=staticwebapps-github-chnoring)
- [Docs: Azure Static Web Apps, Routing](https://docs.microsoft.com/en-us/azure/static-web-apps/routes?WT.mc_id=staticwebapps-github-chnoring)
- [Docs: Azure Static Web Apps, Authentication & Authorization](https://docs.microsoft.com/en-us/azure/static-web-apps/authentication-authorization?WT.mc_id=staticwebapps-github-chnoring)
- [Quickstart: Azure Static Web Apps + Gatsby ](https://docs.microsoft.com/en-gb/azure/static-web-apps/publish-gatsby?WT.mc_id=staticwebapps-github-chnoring)

## 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](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git). 
- **Node.js**, to install Node.js please use `nvm` or grab an installer from this [page](https://nodejs.org/en/download/).
- **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:

```bash
gatsby new <project name>
```

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:

```bash
gatsby develop
```

![Gatsby app in the browser](https://dev-to-uploads.s3.amazonaws.com/i/kbrc21hm2b4g7p2z8349.png)

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

```bash
http://localhost:8000/___graphql
```

![The built-in graph](https://dev-to-uploads.s3.amazonaws.com/i/dx25gkkqnwux6nvsca5n.png)

## 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:

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

export default () => (
  <Layout>
    <div>About</div>
  </Layout>
)
```

Startup your development server with this command:

```bash
gatsby develop
```

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

![Rendered about component](https://dev-to-uploads.s3.amazonaws.com/i/7rfhy3xhvq7nfjbrmaqm.png)

### 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](https://dev-to-uploads.s3.amazonaws.com/i/la0xy9da3sufc4wvlkym.png)

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

```bash
query MyQuery {
  site {
    siteMetadata {
      author
      description
      title
    }
  }
}
```

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

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

```jsx
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
    }
  }
}
`
```

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
1. Create some JSON content
1. Render JSON content that the plugin *sourced* into the built-in data graph.

### Install the plugin

```bash
npm install gatsby-transformer-json
```

### 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:

```json
[{
  "id": 1,
  "name": "ngVikings"
},
{
  "id": 2,
  "name": "Microsoft Build"
}]
```

### 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:

```bash
{
  resolve: `gatsby-source-filesystem`,
  options: {
    name: `images`,
    path: `${__dirname}/src/data`,
  },
}
```

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`:

```js
`gatsby-transformer-json`
```

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

```js
`gatsby-transformer-json`,
{
  resolve: `gatsby-source-filesystem`,
  options: {
    name: `images`,
    path: `${__dirname}/src/data`,
  },
}
```

### Create page component with JSON data

Run the app with the command:

```bash
gatsby develop
```

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](https://dev-to-uploads.s3.amazonaws.com/i/mybqsld97j9evdnlcnz5.png)

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](https://dev-to-uploads.s3.amazonaws.com/i/e9jc9n5bq5krb6htvztw.png)

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

```bash
query MyQuery {
  allProductsJson {
    edges {
      node {
        name
        id
      }
    }
  }
}
```

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

```jsx
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
        }
      }
    }
  }
`
```

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:

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

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

![Rendered products](https://dev-to-uploads.s3.amazonaws.com/i/73djxadyykbvq4taered.png)

## 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.