Migration from Page Context to a Gatsby Page Query

Friday's guest Tayler (@borderless_dev) on the unauthorized and rum-fueled treasure hunt in the sharky waters around the Gatsby islands is our most piratical guest to date 🏴‍☠️

Stream Screendump

Distribute Aid's mission is to provide for basic human needs at scale by connecting communities and empowering people to uphold human dignity.

It ended up being a long one as we completed the refactoring for all the page templates, including some extra work needed for the third one. However, we completed the first migration within the first 30 minutes of the stream if you want to watch how!

The What?

Migrate Distribute Aid's Gatsby site from a page context to page query approach for getting data into their page templates.

The Why?

Pushing all data needed by a page through the page context works and is a straightforward solution I see many developers reach for. However, you then bypass Gatsby goodness, such as hot reloading and incremental builds, by removing the connection between a node and its page.

The How

Instead of pushing through all data on the page context, pass only the node id. Then in the page template, use the node id to query for all data needed.

The Code

Before migration: pushing all data on the page context:

// File: gatsby-node.js
const path = require("path");

exports.createPages = async (gatsbyUtils) => {
  const { graphql, actions } = gatsbyUtils;
  const { createPage } = actions;

  const regionsQuery = await graphql(
    `
      query RegionsQuery {
        regions: allDaRegion {
          nodes {
            slug
            name
            overview
            subregions {
              name
            }
          }
        }
      }
    `
  );

  regionsQuery.data.regions.nodes.forEach((region) => {
    createPage({
      path: `/regions/${region.slug}`,
      component: path.resolve(`./src/templates/RegionPage.js`),
      context: {
        region: region,
      },
    });
  });
};
// File: src/templates/RegionPage.js
import { graphql } from "gatsby";

const RegionPage = ({ pageContext: { region } }) => {
  return <main>{JSON.stringify(region, null, 2)}</main>;
};

export default RegionPage;

After migration, passing only the node id:

// File: gatsby-node.js
const path = require("path");

exports.createPages = async (gatsbyUtils) => {
  const { graphql, actions } = gatsbyUtils;
  const { createPage } = actions;

  const regionsQuery = await graphql(`
    query RegionsQuery {
      regions: allDaRegion {
        nodes {
          id
          slug
        }
      }
    }
  `);

  regionsQuery.data.regions.nodes.forEach((region) => {
    createPage({
      path: `/regions/${region.slug}`,
      component: path.resolve(`./src/templates/RegionPage.js`),
      context: {
        id: region.id,
      },
    });
  });
};
// File: src/templates/RegionPage.js
import { graphql } from "gatsby";

const RegionPage = ({ data: { region } }) => {
  return <main>{JSON.stringify(region, null, 2)}</main>;
};

export default RegionPage;

export const query = graphql`
  query ($id: String!) {
    region: daRegion(id: { eq: $id }) {
      name
      overview
      subregions {
        name
      }
    }
  }
`;

 

Check out the Pull Request on Github to view the full refactor, as the example above is somewhat simplified.

 

All the best,
Queen Raae

 

PS: The Distribute Aid project is a great one to contribute to if you would like to help out or need more real-world Gatsby experience.

Interested in more daily treasures like this one?
Sent directly to your inbox?