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
- Gatsby docs Gatsby's official docs.
- Gatsby tutorials A really good set of tutorials that will take you from your first steps with Gatsby to.
- Gatsby CLI tool I built 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
- Docs: Azure Static Web Apps, add Serverless API
- Docs: Azure Static Web Apps, setup Custom domain
- LEARN module: Gatsby and Azure Static Web Apps
- LEARN module: SPA applications + Serverless API and Azure Static Web Apps
- Docs: Azure Static Web Apps, Routing
- Docs: Azure Static Web Apps, Authentication & Authorization
- Quickstart: Azure Static Web Apps + Gatsby
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 usenpx
and run it when you need it.
To create a Gatsby project type the following in a terminal:
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:
gatsby develop
Next, we want to visit the in-memory data graph. Type the following address in your browser:
http://localhost:8000/___graphql
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:
- Create a page component
- 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>
)
2
3
4
5
6
7
8
Startup your development server with this command:
gatsby develop
Change the URL of your browser to http://localhost:8000/about
, you should see the following being rendered:
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:
In the middle section, you should now have the following query created for you.
query MyQuery {
site {
siteMetadata {
author
description
title
}
}
}
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
}
}
}
`
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:
- Install and configure a plugin
- Create some JSON content
- Render JSON content that the plugin sourced into the built-in data graph.
Install the plugin
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:
[{
"id": 1,
"name": "ngVikings"
},
{
"id": 2,
"name": "Microsoft Build"
}]
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.:
- 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 calledgatsby-source-filesystem
. - 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`,
},
}
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`
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`,
},
}
2
3
4
5
6
7
8
Create page component with JSON data
Run the app with the command:
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:
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:
Make a note of the query by copying it to the clipboard.
query MyQuery {
allProductsJson {
edges {
node {
name
id
}
}
}
}
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
}
}
}
}
`
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>)}
and it renders like so in the browser at http://localhost:8000/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.