Using GraphQL in your Gatsby sites
May 25, 2020
What is Gatsby?
Gatsby is a React framework for generating serverside rendered applications. Gatsby is opinionated, in that it uses GraphQL by default to access interal dependencies such as images or blog posts. It is an excellent tool for setting up static pages, as well as for learning GraphQL which is currently seeing rapid adoption.
What is GraphQL?
GraphQL is a query language for APIs that allows the developer to specify exactly which data they need from the server. It works by connecting a single endpoint to a graph representation of the data. GraphQL is typed, self-documenting, and often preferable to REST when using lots of API endpoints.
Gatsby Setup
In this tutorial we will be using the Gatsby blog starter which is the most popular Gatsby starter, written by Kyle Matthews. This starter has lots of GraphQL queries already written for us to reference and learn from. Setup up a new Gatsby project now by first installing the command line tool
npm install -g gatsby-cli
This will allow you to start a new gatsby project with the command gatsby new project-title
with an optional fourth argument of the link to the starter repo you want to use. Start a new Gatsby blog now by entering the command
gatsby new gatsby-starter-blog https://github.com/gatsbyjs/gatsby-starter-blog
In this tutorial we will mostly be focused on the GraphQL queries rather than the React or blog code itself. If you want to learn more about Gatsby in general, check out this tutorial for the basics.
You can start the project by changing into the project folder and using the command
gatsby develop
Writing Queries (GraphQL Playground)
Running a Gatsby app will start up a development server as usual, in addition to a GraphiQL playground to navigate your project’s dependency graph. Open this in the browser now at
http://localhost:8000/___graphql
In this tool we can write queries on the left and run them on the right. At the far right of the screen there is documentation for our GraphQL queries.
Click on the Query link under ROOT TYPES to view all of the queries we have available along with their inputs. Since GraphQL is a typed language, we can view the inputs for each query and whether they are required.
We can write our first query now with the following syntax (the word query is optional)
query {
}
Place your cursor in between these brackets and you will notice if you press Ctrl + Space or Shift + Space you will have a dropdown autocomplete with the available queries. This feature greatly increases the speed of development and capacity to traverse large APIs efficiently.
Select site
now and you will notice there is a red underline under it. This is because the field does not have a specific value associated with it to return. In this case, site
is similar to a folder that we’re required to specify at least 1 file in.
Open a new set of brackets and you will notice there is another list of available fields to query. Valid GraphQL queries require you to return specific values. Here we can select port
, and underneath it buildTime
so the query looks like
query {
site {
port
buildTime
}
}
Run the query by clicking on the play button and you should see
{
"data": {
"site": {
"port": 8000,
"buildTime": "2020-05-06T15:03:46.000Z"
}
}
}
Once we have specified the data we’re looking for to Gatsby using GraphQL, it will return a JSON representation of that exact data. This is great because it allows developers to focus more on the shape of their API, rather than how they will write queries.
Query Data in Gatsby
There are a few different syntaxes to be aware of for setting up queries in Gatsby
pageQuery
This query works on pages, and can accept context variables unlike static queries. Open up the index.js
file inside the pages folder to see an example of this. At the bottom of the page, below the React component you will see something like
export const pageQuery = graphql`
query {
site {
siteMetadata {
title
}
}
allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }) {
edges {
node {
excerpt
fields {
slug
}
frontmatter {
date(formatString: "MMMM DD, YYYY")
title
description
}
}
}
}
}
`
Gatsby uses GraphQL to query and return the specified information into a props variable data
which can be used in the component.
In this query, the field allMarkdownRemark
loads in the blog post content. This Gatsby blog starter is already set up to build a page in our site for each folder in content/blog
.
This query also contains edges and nodes which are a key concept to graphs. Edges refers to an array of nodes, while Node refers to an invididual entry in that array. The frontmatter
field above will pull in the metadata which is at the top of each example markdown file in the blog.
useStaticQuery
This method is a hook for using GraphQL in any functional component. This query can be included inside the component itself, unlike the page query component which goes below it. If you open the bio.js
component you will see an example useStaticQuery
hook
const data = useStaticQuery(graphql`
query BioQuery {
avatar: file(absolutePath: { regex: "/profile-pic.jpg/" }) {
childImageSharp {
fixed(width: 50, height: 50) {
...GatsbyImageSharpFixed
}
}
}
site {
siteMetadata {
author {
name
summary
}
social {
twitter
}
}
}
}
`)
In this example we have a named query BioQuery
(query names are arbitrary and optional) that returns an avatar and data about the site. The syntax avatar:
is similar to aliasing parameters in ES6 by setting the file
field to avatar
. Here there is also an absolutePath
regex string is passed into the file query which will attempt to match the specific file.
Under avatar
we also have a field childImageSharp
. Gatsby does a lot in the background to optimize and serve multiple image sizes in your project. There is plenty to learn about the image component which could be a tutorial in and of itself. For now, it is at least important to be aware that this is how the images are loaded, and that childImageSharp
currently does not work in the GraphIQL playground in the browser because it uses a fragment (i.e. …GatsbyImageSharpFixed). If you are having issues running queries such as the one above, make sure to temporarily replace or remove this fragment from the query.
Conclusion
Gatsby is a pioneering modern web framework that is doing a lot right in terms of making serverside rendering and GraphQL more approachable. I highly recommend building Gatsby sites as an intro to learning more about GraphQL.