gatsbyjs / gatsby

The best React-based framework with performance, scalability and security built in.
https://www.gatsbyjs.com
MIT License
55.28k stars 10.31k forks source link

SOLVED - Gatsby v2 WordPress post.js and page.js - Variable "$id" of required type "String!" was not provided. #8242

Closed SimonIMG closed 5 years ago

SimonIMG commented 6 years ago

Description

I'm building a Gatsby site with a WordPress and ACF backend. I've been following the example closely to build my decoupled site, in particular, the template files for post.js and page.js.

However, when I go a gatsby develop I get the following error for my pages (although the site displays correctly in gatsby develop mode). I get a similar one for posts as well.

Errors:
  Variable "$id" of required type "String!" was not provided.

GraphQL request (2:3)
  1: query usersSimonolsenWorkProjectsIncrementalSiteFrontendWwwgatsbySrcPagesPageJs2860193164(
  2:   $id: String!
       ^
  3: ) {

URL path:
  /page/
Context:
  {}
Plugin:
  none
Query:
  query usersGiantPathToMyLocalGatsbySiteSrcPagesPageJs2860193164(
    $id: String!
  ) {
    wordpressPage(id: {eq: $id}) {
      id
      content
      slug
      title
      acf {
        content_page {
          __typename
          ... on WordPressAcf_text_block {
            columns
            id
            text
            text_2
            text_3
            text_4
          }
          ... on WordPressAcf_video_block {
            caption
            id
            video
          }
          ... on WordPressAcf_standout_quote {
            id
            quote_background_image {
              id
              source_url
            }
            quote_text
          }
        }
      }
    }
  }

I know this is going to make my gatsby build fail, so trying to find what I have done wrong.

Steps to reproduce

As you can see from the query in the error, I set up my page.js and post.js much like the template files in the WP example.

Expected result

gatsby develop run without these errors - the $id is provided.

Actual result

Variable "$id" of required type "String!" isn't provided and I get those errors which will eventually prevent gatsby build from working.

Environment

System: OS: macOS Sierra 10.12.6 CPU: x64 Intel(R) Core(TM) i7-3840QM CPU @ 2.80GHz Shell: 3.2.57 - /bin/bash Binaries: Node: 10.8.0 - /usr/local/bin/node Yarn: 1.9.4 - /usr/local/bin/yarn npm: 6.2.0 - /usr/local/bin/npm Browsers: Chrome: 69.0.3497.100 Firefox: 61.0.2 Safari: 11.1.2 npmPackages: gatsby: next => 2.0.0-rc.10 gatsby-plugin-manifest: next => 2.0.2-rc.1 gatsby-plugin-offline: next => 2.0.0-rc.2 gatsby-plugin-react-helmet: ^3.0.0-rc.1 => 3.0.0-rc.1 gatsby-source-filesystem: ^1.5.39 => 1.5.39 gatsby-source-wordpress: ^2.0.93 => 2.0.93 npmGlobalPackages: gatsby-cli: 1.1.58

kakadiadarpan commented 6 years ago

@SimonIMG can you provide a reproduction repo for this? That would make it much simpler to diagnose this issue.

SimonIMG commented 6 years ago

It's a private repo for my place of employment, sorry.

And pulling it down and running it likely won't work, as it is connected to a Lando instance on my local machine.

I was hoping someone else had come across this issue.

Here is my gatsby-node.js

const _ = require('lodash');
const Promise = require('bluebird');
const path = require('path');

exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions;
  return new Promise((resolve, reject) => {
    graphql(`
      {
        allWordpressPage {
          edges {
            node {
              id
              path
              slug
            }
          }
        }
        allWordpressPost {
          edges {
            node {
              id
              path
              slug
            }
          }
        }
      }
    `).then((result) => {
      if (result.errors) {
        console.log(result.errors);
        reject(result.errors);
      }

      _.each(result.data.allWordpressPage.edges, (edge) => {
        createPage({
          path: `/${edge.node.path}/`,
          component: path.resolve('./src/pages/page.js'),
          context: {
            id: edge.node.id,
            slug: edge.node.slug,
          },
        });
      });

      _.each(result.data.allWordpressPost.edges, (edge) => {
        createPage({
          path: `/blog/${edge.node.slug}`,
          component: path.resolve('./src/pages/post.js'),
          context: {
            id: edge.node.id,
            slug: edge.node.slug,
          },
        });
      });

      resolve();
    });
  });
};

And here is my page.js that's throwing the error

import React, { Component } from 'react';
import { graphql } from 'gatsby';
import PropTypes from 'prop-types';

import Layout from '../components/layout';

export default class Page extends Component {
  render() {
    const { data } = this.props;
    return (
      <Layout>
        <h1 dangerouslySetInnerHTML={{ __html: data.wordpressPage.title }} />
      </Layout>
    );
  }
}

Page.propTypes = {
  data: PropTypes.object.isRequired,
  edges: PropTypes.array,
};

export const pageQuery = graphql`
  query($id: String!) {
    wordpressPage(id: { eq: $id }) {
      id
      content
      slug
      title
    }
  }
`;

Is this enough to diagnose what's going on?

SimonIMG commented 6 years ago

So, in my page.js file, if I change the query so that a String is not required, the error is gone.

export const pageQuery = graphql`
  query($id: String) {
    wordpressPage(id: { eq: $id }) {
      id
      content
      slug
      title
    }
  }
`;

But does that mean there is WP content being generated that doesn't have an ID? Or a slug? How could that be?

larryPersonal commented 6 years ago

Note: have similar questions using another CMS entirely, in this case Contentful.

The migration example at https://next.gatsbyjs.org/docs/migrating-from-v1-to-v2/#dont-query-nodes-by-id only has an example that shows how to update an image query.

If anything there needs to be an example for structures like:

query  pageQuery ($id: String!) {
    allContentfulPage(
        filter: { id: { eq: $id } }
    ) { ...

As this seems to be a common enough pattern.

SimonIMG commented 6 years ago

@larryPersonal so you're getting the same error?

Variable "$id" of required type "String!" was not provided.

larryPersonal commented 6 years ago

@SimonIMG that statement worked for me; contentful page id is a string.

smakosh commented 6 years ago

I'm getting the same error, looking for a solution

SimonIMG commented 6 years ago

Hi @smakosh. I just left my String as not required. Our relatively large and complex Gatsby site with WP backend has gone live and had no problems.

All pages are rendering in gatsby develop and gatsby build fine.

If you manage to work this out with the String required, please share. But for now, if you're struggling with this (and no one else has any reason to not recommend this due to security or performance) simply remove the ! from the String.

query($id: String) {
  wordpressPage(id: { eq: $id }) {
    id
    content
    slug
    title
  }
}
smakosh commented 6 years ago

By removing the !, I get the same content on each page even though the slug changes which is weird, while the query works just fine on the GraphiQL playground

blkfltchr commented 6 years ago

By removing the !, I get the same content on each page even though the slug changes which is weird, while the query works just fine on the GraphiQL playground

The same thing happens for me! @SimonIMG is there anything else we should be looking for so that the individual posts render dynamically? What happens without the ! is that my first post renders at all slugs

Here is a snippet from my gatsby-node.js file:

// Create each individual post
      posts.forEach(({edge}, index) => {
        createPage({
          path: edge.node.slug, 
          component: path.resolve(`./src/templates/blogPost.js`),
          context: {
            pathSlug: edge.node.slug,
            prev: index === 0 ? null : posts[index - 1].node,
            next: index === (posts.length - 1) ? null : posts[index + 1].node,
          },
        })
      })

And here is how I reference it on blogPost.js:

export const query = graphql`
  query blogPostQuery($pathSlug: String!){
    contentfulBlogPost(slug: {eq: $pathSlug}) {
      title
      slug
      tags
      body {
        childMarkdownRemark {
          html
        }
        }
      }
  }
`
SimonIMG commented 6 years ago

Hmmm. My site is using a WordPress instance as the backend. @blkfltchr and @larryPersonal you both have Contentful as yours. But hopefully, there are things we can compare between the two.

@blkfltchr your query says contentfulBlogPost(slug: {eq: $pathSlug}) but in my WordPress example in my original post, I'm querying wordpressPage(id: { eq: $id }).

My query is looking for the Page and Post ID, as opposed to the slug.

Are you able to do the same with your query to your Contentful backend? Query your content ID instead of the slug? It might be worth a shot.

blkfltchr commented 6 years ago

@SimonIMG @smakosh I was able to sort it by changing my posts.forEach() from this:

posts.forEach(({edge}, index) => {
        createPage({
          path: edge.node.slug, 
          component: path.resolve(`./src/templates/blogPost.js`),
          context: {
            pathSlug: edge.node.slug,
            ...

to this:

posts.forEach(({node}, index) => {
        createPage({
          path: node.slug, 
          component: path.resolve(`./src/templates/blogPost.js`),
          context: {
            pathSlug: node.slug,
            ...
SimonIMG commented 6 years ago

Awesome! Glad you got it sorted.

smakosh commented 6 years ago

Thanks but my issue has been sorted out weeks ago

1-800-jono commented 5 years ago

I'm having the same issue as well. I suspect it has to do with having the files inside /pages directory. I tried the above solution and still getting the error.

I'm using Netlify CMS.

gatsbot[bot] commented 5 years ago

Hiya!

This issue has gone quiet. Spooky quiet. 👻

We get a lot of issues, so we currently close issues after 30 days of inactivity. It’s been at least 20 days since the last update here.

If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!

Thanks for being a part of the Gatsby community! 💪💜

AfroDevGirl commented 5 years ago

I'm having the same issue after adding more posts to my wordpress site. It was working with no issues before adding more posts today. All posts have ids and slugs yet this query has broken down for seemingly no reason.

gatsbot[bot] commented 5 years ago

Hey again!

It’s been 30 days since anything happened on this issue, so our friendly neighborhood robot (that’s me!) is going to close it.

Please keep in mind that I’m only a robot, so if I’ve closed this issue in error, I’m HUMAN_EMOTION_SORRY. Please feel free to reopen this issue or create a new one if you need anything else.

Thanks again for being part of the Gatsby community!

fsgreco commented 5 years ago

Errors: Variable "$id" of required type "String!" was not provided.

GraphQL request (2:3) 1: query usersSimonolsenWorkProjectsIncrementalSiteFrontendWwwgatsbySrcPagesPageJs2860193164( 2: $id: String! ^ 3: ) {

URL path: /page/ Context: {} Plugin: none Query: query usersGiantPathToMyLocalGatsbySiteSrcPagesPageJs2860193164( $id: String! )

@SimonIMG This problem happened because the template of the page was inside the "pages" folder, so in addition gatsby was generating a page with the path /page/ (look at the quote above in strong)

By removing the " ! " in String the error was not warned but was still there. I just manage to solved it moving the "page.js" template into another custom folder and then updating the path on the gatsby-node.js.

SimonIMG commented 5 years ago

@anonimoconiglio OK, I'll try this out on our site and see what happens.

SimonIMG commented 5 years ago

@anonimoconiglio you're spot on! And it so happens that I have already moved my page.js, post.js and other CPT .js files into a new, custom folder (/src/templates for anyone who is interested).

I've added the required ! marker to the String and it's working perfectly.

Thank you!

fsgreco commented 5 years ago

@SimonIMG you're welcome, spend quite time trying to fix it yesterday, hope it will be useful to anybody with this problem :)

Manuelandro commented 5 years ago

I got the same error but my page template is not inside a "pages" folder.

gatsby-node.js

const staticTemplate = path.resolve('./src/templates/static.js')
  allWordpressPage.edges.forEach(edge => {
    createPaginatedPages({
      edges: allWordpressPage.edges,
      createPage: createPage,
      pageTemplate: staticTemplate,
      pageLength: 8,
      pathPrefix: `/${edge.node.slug}/`,
      context: {
        id: edge.node.id,
      },
    })
  })

static.js

export const query = graphql`
  query($id: String!) {
    wordpressPage(id: { eq: $id }) {
      id
      content
      slug
      title
    }
  }
...

Errors: Variable "$id" of required type "String!" was not provided.

bastianhilton commented 4 years ago

Hi @smakosh. I just left my String as not required. Our relatively large and complex Gatsby site with WP backend has gone live and had no problems.

All pages are rendering in gatsby develop and gatsby build fine.

If you manage to work this out with the String required, please share. But for now, if you're struggling with this (and no one else has any reason to not recommend this due to security or performance) simply remove the ! from the String.

query($id: String) {
  wordpressPage(id: { eq: $id }) {
    id
    content
    slug
    title
  }
}

Had the same issue but in Gridsome:

query($id: ID){
  posts(id: $id){
    name
    content
    path
    id
  }
}

I removed the ! after ID and the error went away. That's weird, wonder why so many tutorials put it on there if you can just remove it.