Search code examples
javascriptreactjsgraphqlgatsbystoryblok

How to create multiple page types dynamically in Gatsby-node.js


I create a new page per post for my blogpost storybook content in my Gatsby-node.js like so:

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

  return new Promise((resolve, reject) => {
    const storyblokEntry = path.resolve('src/templates/blog-entry.js')

    resolve(
      graphql(
        `{
          stories: allStoryblokEntry(filter: {field_component: {eq: "blogpost"}}) {
            edges {
              node {
                id
                name
                slug
                field_component
                full_slug
                content
              }
            }
          }
        }`
      ).then(result => {
        if (result.errors) {
          console.log(result.errors)
          reject(result.errors)
        }

        const entries = result.data.stories.edges

        entries.forEach((entry) => {
          const page = {
            path: `/${entry.node.full_slug}`,
            component: storyblokEntry,
            context: {
              story: entry.node
            }
          }
          createPage(page)
        })
      })
    )
  })
}

But I also want to create a page per post for another content type called locations which is set up in the same way:

Component src/templates/locations.js

Storyblok Field Component "locations"

How do I create both the page types inside Gatsby-node.js? Any help would be hugely appreciated!


Solution

  • You need to refactor your approach, assigning one variable for each query result, one for entries (result1) and one for locations (result2). The next step is to proceed in the same way, iterating for each result and calling createPage for each desired value.

     const path = require(`path`)
        const { createFilePath } = require(`gatsby-source-filesystem`)
        
        exports.createPages = async ({ graphql, actions, reporter }) => {
          const { createPage } = actions
          const storyblokEntry = path.resolve('src/templates/blog-entry.js')
          const storyblokLocation = path.resolve('src/templates/locations.js')
    
          const result1 = await graphql(`{
                  stories: allStoryblokEntry(filter: {field_component: {eq: "blogpost"}}) {
                    edges {
                      node {
                        id
                        name
                        slug
                        field_component
                        full_slug
                        content
                      }
                    }
                  }
                }`
          )
        
          if (result1.errors) {
            reporter.panicOnBuild(
              `There was an error loading your blog posts`,
              result.errors
            )
            return
          }
        
          const entries = result1.data.stories.edges
        
          entries.forEach((entry) => {
            const page = {
              path: `/${entry.node.full_slug}`,
              component: storyblokEntry,
              context: {
                story: entry.node
              }
            }
            createPage(page)
          })
        
          //add here your query to locations schema. I've used your previous one
          const result2 = await graphql(`{ //
                  stories: allStoryblokEntry(filter: {field_component: {eq: "blogpost"}}) {
                    edges {
                      node {
                        id
                        name
                        slug
                        field_component
                        full_slug
                        content
                      }
                    }
                  }
                }`
          )
          if (result2.errors) {
            reporter.panicOnBuild(
              `There was an error loading your blog posts`,
              result.errors
            )
            return
          }
        
          const locations = result2.data.stories.edges
          locations.forEach((entry) => {
            const page = {
              path: `/${entry.node.full_slug}`, //customize with your data
              component: storyblokLocation, //customize with your data
              context: {
                story: entry.node //customize with your data
              }
            }
            createPage(page)
          })
        }