Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GraphQL Error on pages that query conditionally added SitePage fields #2685

Closed
fusepilot opened this issue Oct 31, 2017 · 4 comments
Closed

Comments

@fusepilot
Copy link
Contributor

Repro: https://github.com/fusepilot/gatsby-page-query-conditional-field-repro
Possibly Related: #1718

I'm adding a custom field using createNodeField to certain pages of my site. I get a compile time GraphQL error unless I add the field to all pages. Everything works fine at runtime.

GraphQL Error Unknown field `fields` on type `SitePage`

  file: /Users/michaeldelaney/Downloads/gatsby-starter-default-master 2/src/pages/index.js

   1 |
   2 |   query IndexQuery {
   3 |     allSitePage {
   4 |       edges {
   5 |         node {
>  6 |           fields {
     |           ^
   7 |             foo
   8 |           }
   9 |         }
  10 |       }
  11 |     }
  12 |   }
  13 |

The relevant code:

// gatsby-node.js

// define a field on certain pages
function conditionalCreateNodeField({ node, createNodeField }) {
  if (node.path == '/page-a/') {
    createNodeField({
      node,
      name: 'foo',
      value: 'bar a',
    })
  }
}

// define a field on all pages
function unconditionalCreateNodeField({ node, createNodeField }) {
  createNodeField({
    node,
    name: 'foo',
    value: 'bar',
  })
}

exports.onCreateNode = async ({ node, boundActionCreators }) => {
  const { createNodeField } = boundActionCreators

  if (node.internal.type == 'SitePage') {
    conditionalCreateNodeField({ node, createNodeField }) // throws GraphQL Error
    // unconditionalCreateNodeField({ node, createNodeField }) // no error
  }
}
// index.js

export const pageQuery = graphql`
  query IndexQuery {
    allSitePage {
      edges {
        node {
          fields {
            foo
          }
        }
      }
    }
  }
`
@KyleAMathews
Copy link
Contributor

In Gatsby v1, SitePages wasn't intended to be queried as part of building a site — It was only added as a debugging tool — e.g. a quick way to introspect on some core data. Since launching v1 there's been several people giving feedback about why this would be super useful to have e.g. for auto-generating menus, etc.

But there needs to be some internal changes first for this to work namely regenerating the GraphQL schema for pages after pages are added (which happens after the first time the GraphQL schema is generated).

If this is something you'd like to take on, would love to get you going on a PR adding this!

@fusepilot
Copy link
Contributor Author

I can give it a shot! Would love any pointers you have on where to start and generally what needs to happen.

@KyleAMathews
Copy link
Contributor

Sweet!

So basically much of the Gatsby magic is coordinated in this file https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/src/bootstrap/index.js

What you'll want to do is to add a new bootstrap step here which now that we've collected page information, generates the full page schema (we cheat a bit and add a fake page node earlier so there's a minimal SitePage schema available earlier).

The tricky this is we don't want to regenerate the full GraphQL schema again as on large sites that can start taking 500ms+ so starts getting expensive. Ideally we'd regenerate just the page type and overwrite the previously created one which should be cheap enough to do.

Lemme know if you have more questions! This would be great to get in.

@fusepilot
Copy link
Contributor Author

Fixed in #2710.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants