DEV Community

Cover image for Reading Data From A JSON File With Gatsby + GraphQL
Emma Bostian ✨
Emma Bostian ✨

Posted on • Updated on

Reading Data From A JSON File With Gatsby + GraphQL

Goal: Use gatsby-transformer-json to read data from a local JSON file and dynamically generate list items in a React component.

Use Case: I have a Sidebar React component that takes in an array of sidebar list items (objects) and dynamically generates list items from their data. I don't want to hard-code all of the sidebar values, as this can quickly become unruly. Thus, I want to have a JSON file where I can quickly add a new list item and have it propagate to the UI.

This blog assumes you already have a Gatsby project created. You can use the Gatsby CLI to quickly spin up a new application. My sidebar.js component is being imported into the index.js starter file that is generated after running the CLI command.

  1. Create the directory and JSON file where you will store your JSON data. Mine will live inside src/data/sidebarItems.json.

My JSON data has the following structure:

Code

  1. Next, install gatsby-transformer-json and gatsby-source-filesystem.
npm install gatsby-transformer-json gatsby-source-filesystem --save
  1. Inside of the gatsby-config.js file, add the following:

Code

The path value will be the link to the folder which contains your JSON file.

  1. Next, open the component you want to use your data. Mine lives inside of sidebar.js

First, import StaticQuery and graphql from gatsby. We'll need these to access our JSON data.

Code

We'll use Gatsby's Static Query to wrap a stateless functional React component.

Inside of the <StaticQuery /> elements, add two attributes: query and render.

Query Attribute

The value of the query attribute will look like this:

Code

We're creating a query called SidebarItemsQuery (you can name the query however you like; I choose to name it {dataReturned}Query). The data returned will be the sidebar items, so the query name will be SidebarItemsQuery.

Next we have the allSidebarItemsJson. You must name this in accordance with your JSON file name. Since I had SidebarItems.json, this is called allSidebarItemsJson. This is the default naming convention, however you can change this inside of gatsby-config.js (see "Chaning the Default gatsby-transformer-json Naming Convention" section at the end for more details).

Inside of that we have edges, node, and then the values we want to return from our query. In my case, since I'm creating a sidebar with a list of links to different content, I have a label and a link (See "GraphQL Nomenclature" section below for a high-level definition of edges and nodes).

Render Attribute

Now that we have our query, let's define the render attribute. This attribute will take one parameter: the data from the query we just wrote. It will return the JSX we want the stateless functional component to render.

Note: You can wrap your JSX in empty brackets <>...</> as a shorthand for a React fragment. This allows you to return multiple child components without appending additional nodes to the DOM.

Code

This is the same as writing this:

Code

Now, I want to iterate over these nodes and create an <h1> for each label; it might look something like this. I've created a getSidebarLabels helper function, which takes in the data and iterates over it to create three <li> items.

Code

The helper function is as follows:

Code

And just as we'd expect, three list items are appended to the DOM.

UI

Here is the full code for the stateless functional component in sidebar.js.

Code

GraphQL Nomenclature

GraphQL uses graphs to represent data. You can picture it to look something like this:

Graphql

Edges: The lines that connect different nodes in the graph and represent a relationship.

Nodes: Records or data.

Let's take the example of a blogging website like Medium. Nodes, in this use case, can be thought of as blog posts or users.

Graphql

I am not an expert on GraphQL; I'm still learning! Feel free to leave a comment down below if I misrepresented something.

Changing the Default gatsby-transformer-json Naming Convention

To change the JSON query, head over to gatsby-config.js, and replace the "gatsby-transformer-json" line with the object below.

Inside of the options object, update the typeName key; this can be any string value. Here, we've put the static value of Json, although it's important to note that this is just a string value, so you could call it Cats if you'd like.

Code

Now, inside of the file where we created the GraphQL query (sidebar.js in my case), reference the newly named typeName value in the query with all{typeName}.

Code


Now you know how to use gatsby-transformer-json to read data from a local JSON file. I primarily wrote this blog post for my own benefit (I'll probably need to reference it later), so there may be some minor errors. If you find any, please let me know in the comments below. :)

Top comments (12)

Collapse
 
walaszczyk_m profile image
Maciej Walaszczyk

Great post, Emma 👌

I have found a mistake with explaining empty brackets in JSX. You are putting:

<>
  <h1>Hello world</h1>
  <p>Another child component</p>
<>

as the same as

<div>
  <h1>Hello World</h1>
  <p>Another child component</p>
<div>

which is not true.

The true equivalent is

<React.Fragment>
  <h1>Hello World</h1>
  <p>Another child component</p>
</React.Fragment>
Collapse
 
nateosterfeld profile image
Nate Osterfeld

I was unsure of this in the regard of whether or not it compiled to a div tag at runtime, in which case I'd say your comment would be a little nitpicky, since she probably knows this and assumes it's easier to say it's a div than having to explain Fragment, but it actually doesn't get compiled to anything. Essentially the same thing, though, sorta. Okay mini rant over.

Collapse
 
raymondcamden profile image
Raymond Camden

Query - I love GraphQL (recent convert!) but I'm curious why it was used here? Given that the JSON data was static, not an API, and was already in a simple to use format, what was the purpose of using GraphQL to "query" it? Wasn't it already in a form appropriate for driving your dynamic navigation?

Collapse
 
lucis profile image
Lucis

Read about Gatsby. It's built for reusability (themes) and GraphQL powers that. If she would release her creation as a theme, a user could build their own json in their own data folder, and Gatsby would resolve it.

Collapse
 
vaidotas profile image
Vaidotas Piekus

This is awesome Emma. I want to rewrite my personal site using Gatsby and this is gonna be super helpful!

Collapse
 
emmabostian profile image
Emma Bostian ✨

Aw yay! <3

Collapse
 
ianfabs profile image
Ian Fabs

this was actually so helpful, thank you!! i was looking for a way do this all day!

Collapse
 
stevexm profile image
Steve Melnikoff

Thank you, a very useful post that helped me better understand how to work with GraphQL!

Collapse
 
krichdev profile image
Kyle Richardson

Have you tried filtering on your query with this transformer plugin? I am trying to filter by a value and I’m not having any luck.

Collapse
 
zeptobook profile image
ZeptoBook

Here is a step by step guide about how to create your blog site using Gatsby.
zeptobook.com/create-your-blog-sit...

Collapse
 
tomekponiat profile image
Tomek Poniatowicz

Hey Emma, if you need a GraphQL schema visualization tool take a look at graphqleditor.com/

Collapse
 
luispa profile image
LuisPa

Great post!