gatsby

GatsbyJS - how to set up gatsby-node.ts with createPages?


I was migrating my Gatsby site to typescript and followed the official guide to update gatsby-node.js to .ts file. The js file works fine but ts file not. The only differences are:

  1. exports.createPages changed to export const sourceNodes: GatsbyNode["createPages"]
  2. import type { GatsbyNode } from "gatsby" added at the top

Here is the gatsby-node.ts that doesn't work.

import type { GatsbyNode } from "gatsby"
import path from "path"

export const sourceNodes: GatsbyNode["createPages"] = async ({ graphql, actions, reporter }) => {
    const { createPage } = actions
    const result:any = await graphql(`
        query {
            allMdx {
                edges {
                    node {
                        id
                        slug
                    }
                }
            }
        }
    `)
    if (result.errors) {
        reporter.panicOnBuild('🚨  ERROR: Loading "createPages" query')
    }
    
    const posts = result.data?.allMdx.edges

    posts.forEach(({ node }) => {
        createPage({
            path: `/work/${node.slug}`,
            component: path.resolve(`./src/components/works-layout.tsx`),
            context: { id: node.id },
        })
    })
}

And the gatsby-node.js that works:

import path from "path"

exports.createPages = async ({ graphql, actions, reporter }) => {
    const { createPage } = actions
    const result = await graphql(`
      query {
        allMdx {
          edges {
            node {
              id
              slug
            }
          }
        }
      }
    `)
    if (result.errors) {
      reporter.panicOnBuild('🚨  ERROR: Loading "createPages" query')
    }
    
    const posts = result.data.allMdx.edges
    posts.forEach(({ node }) => {
      createPage({
        path: `/work/${node.slug}`,
        component: path.resolve(`./src/components/works-layout.tsx`),
        context: { id: node.id },
      })
    })
  }

Here is compile report with the error:

warn The GraphQL query in the non-page component
"/Users/cindyho/portfolio/src/components/works-layout.tsx" will not be run.
Exported queries are only executed for Page components. It's possible you're
trying to create pages in your gatsby-node.js and that's failing for some
reason.

If the failing component(s) is a regular component and not intended to be a page
component, you generally want to use a <StaticQuery>
(https://gatsbyjs.com/docs/static-query)
instead of exporting a page query.

If you're more experienced with GraphQL, you can also export GraphQL
fragments from components and compose the fragments in the Page component
query and pass data down into the child component —
https://graphql.org/learn/queries/#fragments


Solution

  • You have to convert exports.createPages = () => {} to export const createPages = () => {}.

    Currently you have export const sourceNodes where the createPage action won't be called. It has to happen in the createPages lifecycle.