How to work with data in Gatsby

In this article, we will learn how to create, access and render data in Gatsby application.

There are 2 options to store data in Gatsby

  • Local: JSON, Markdown, MDX
  • External: Headless CMS (Contentful, Strapi)

I. Contentful

1. Create acount and content

We firstly need to sign up or login into our Contenful account: https://www.contentful.com/

After logged in, we can create a new project, create content type and add content.

For example, we create 3 sample products that have:

  • tittle
  • slug
  • price
  • image
  • info

You can learn more about Contentful at Contentful Learning Center

2. Connect Gatsby to Contenful

Step 1: Install Contenful plugin

We need to install Contentful plugin to pull content types and data into Gatsby from Contentful.

npm install gatsby-source-contentful

Step 2: Edit gatsby-config.js

// In gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-contentful`,
      options: {
        spaceId: `your_space_id`,
        // Learn about environment variables: https://gatsby.dev/env-vars
        accessToken: `YOUR_ACCESS_TOKEN`,
      },
    },
  ],
};

Step 3: Create Environment Variables

To protect your accessToken, we need to use Environment Variables

  • In our root directory, create .env.development file and fill in your token.

In this example, I name the variable as ACCESS_TOKEN

ACCESS_TOKEN=YOURTOKEN

Because .gitignore file already ignores .env*, so our ACCESS_TOKEN variable won’t be pushed to Github

  • Require a Node package in gatsby-config.js
// In gatsby-config.js

require("dotenv").config({
  path: `.env.${process.env.NODE_ENV}`,
});

module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-contentful`,
      options: {
        spaceId: `your_space_id`,
        // Learn about environment variables: https://gatsby.dev/env-vars
        accessToken: process.env.ACCESS_TOKEN,
      },
    },
  ],
};

3. Product query

We can view our Contentful query in GraphiQL

{
    allContentfulProduct {
        nodes {
        id
        price
        title
        slug
        image {
            fluid {
            ...GatsbyContentfulFluid
            }
        }
        }
    }
}

The field name in GraphiQL will match exactly what we have in Content model

4. Apply our data

Here is an example of a Product page

import React from "react"
import { graphql } from "gatsby"
import Layout from "../components/layout"
import styles from "../css/products.module.css"
import Image from "gatsby-image"

const Product = ({ data }) => {
  const {
    allContentfulProduct: { nodes: products },
  } = data

  return (
    <Layout>
      <section className={styles.page}>
        {products.map(product => {
          return (
            <article key={product.id}>
              <Image fluid={product.image.fluid} alt={product.title}></Image>
              <h3>
                {product.title} <span>${product.price}</span>
              </h3>
            </article>
          )
        })}
      </section>
    </Layout>
  )
}

export const query = graphql`
  {
    allContentfulProduct {
      nodes {
        id
        price
        title
        slug
        image {
          fluid {
            ...GatsbyContentfulFluid
          }
        }
      }
    }
  }
`

export default Product