Gatsby: [gatsby-source-graphql] No localFile on featuredImage from Wordpress

Created on 27 Jul 2019  路  10Comments  路  Source: gatsbyjs/gatsby

What's the current situation with gatsby-image and querying it through gatsby-source-graphql. With REST API and gatsby-source-wordpress the query looked like this:

featured_media {
  alt_text
  localFile {
    childImageSharp {
      fluid(maxWidth: 1200, maxHeight: 600, cropFocus: CENTER, quality: 100) {
        ...GatsbyImageSharpFluid
        srcSet
      }
    }
  }
}

The localFile or imageSharp is no where to find on the featured_media when used along side gatsby-source-graphql.

Is this on gatsby-source-graphql's end or does it have to do with some of the external plugins as such as gatsby-plugin-sharp?

Most helpful comment

Hi @fabianderijk, the workaround was to use the gatsby-source-filesystem in combination with your gatsby-source-graphql package to fetch and create a media type that allows the usage of featuredImage. Below is the packages I included in my gatsby-config file:

{
  resolve: `gatsby-source-filesystem`,
  options: {
    path: path.resolve(`./src`) // this should be your folder containing project files
  }
},
{
  resolve: "gatsby-source-graphql",
  options: {
    typeName: "WP",
    fieldName: "wp", // the query name
    url: "INSERT_YOUR_GRAPHQL_ENDPOINT"
  }
},

And in my gatsby-node file I would then fetch the remote files and create nodes that would allow me to use ImageSharp:

const { createRemoteFileNode } = require(`gatsby-source-filesystem`);

exports.createResolvers = ({
  actions,
  cache,
  createNodeId,
  createResolvers,
  store,
  reporter
}) => {
  const { createNode } = actions;
  createResolvers({
    WP_MediaItem: {
      imageFile: {
        type: `File`,
        resolve(source, args, context, info) {
          return createRemoteFileNode({
            url: source.sourceUrl,
            store,
            cache,
            createNode,
            createNodeId,
            reporter
          });
        }
      }
    }
  });
};

The above would create a query type imageFile on WP_MediaItem, which allows you to query for ImageSharp. An example of this is seen below:

export const query = graphql`
  query PageQuery($uri: String) {
    wp { // remember this from the query name in gatsby-source-graphql?
      pageBy(uri: $uri) {
        featuredImage {
          sourceUrl
          altText
          imageFile { // this is the node we created in gatsby-node
            childImageSharp {
              fluid(
                maxWidth: 2000
                maxHeight: 1000
                cropFocus: ATTENTION
                grayscale: true
              ) {
                ...GatsbyImageSharpFluid_withWebp
                srcSet
              }
            }
          }
        }
      }
    }
  }
`;

Hope this clarified the issue. If not, feel free to reach out 馃憤.

All 10 comments

Hi @omattman, you closed this issue, now i have the same issue. What was the issue you had and hoe die you fix it?

Hi @fabianderijk, the workaround was to use the gatsby-source-filesystem in combination with your gatsby-source-graphql package to fetch and create a media type that allows the usage of featuredImage. Below is the packages I included in my gatsby-config file:

{
  resolve: `gatsby-source-filesystem`,
  options: {
    path: path.resolve(`./src`) // this should be your folder containing project files
  }
},
{
  resolve: "gatsby-source-graphql",
  options: {
    typeName: "WP",
    fieldName: "wp", // the query name
    url: "INSERT_YOUR_GRAPHQL_ENDPOINT"
  }
},

And in my gatsby-node file I would then fetch the remote files and create nodes that would allow me to use ImageSharp:

const { createRemoteFileNode } = require(`gatsby-source-filesystem`);

exports.createResolvers = ({
  actions,
  cache,
  createNodeId,
  createResolvers,
  store,
  reporter
}) => {
  const { createNode } = actions;
  createResolvers({
    WP_MediaItem: {
      imageFile: {
        type: `File`,
        resolve(source, args, context, info) {
          return createRemoteFileNode({
            url: source.sourceUrl,
            store,
            cache,
            createNode,
            createNodeId,
            reporter
          });
        }
      }
    }
  });
};

The above would create a query type imageFile on WP_MediaItem, which allows you to query for ImageSharp. An example of this is seen below:

export const query = graphql`
  query PageQuery($uri: String) {
    wp { // remember this from the query name in gatsby-source-graphql?
      pageBy(uri: $uri) {
        featuredImage {
          sourceUrl
          altText
          imageFile { // this is the node we created in gatsby-node
            childImageSharp {
              fluid(
                maxWidth: 2000
                maxHeight: 1000
                cropFocus: ATTENTION
                grayscale: true
              ) {
                ...GatsbyImageSharpFluid_withWebp
                srcSet
              }
            }
          }
        }
      }
    }
  }
`;

Hope this clarified the issue. If not, feel free to reach out 馃憤.

@omattman
Struggling to create the resolver part of this code.
I never get to see the imageFile in graphiQL.. its not being created.
What do I need to debug to see where this isn't working.
console.log(what?) to see nodes created by resolver..

I've literally pasted the code above into gatsby-node.js but can't figure out what is not working.
I'd would so appreciate any pointers, thank you 馃檹

Same for me, source.sourceUrl is undefined when the resolver is called

Hi @h0rhay and @antoinerousseau. Sorry I haven't been able to reach out sooner.

Things have changed in both Gatsby and the GraphQL plugin which made my previous answer redundant. In particular there's changes to how we query the featuredImage and how the resolver is structured.

Remark: my resolver handles issues with non-english letters being escaped by encodeURI. If this isn't needed in your case you can omit the selective statement and encode function.

Start by updating the resolver in gatsby-node.js:

exports.createResolvers = async ({
  actions,
  cache,
  createNodeId,
  createResolvers,
  store,
  reporter,
}) => {
  const { createNode } = actions;

  await createResolvers({
    WP_MediaItem: {
      imageFile: {
        type: `File`,
        async resolve(source) {
          let sourceUrl = source.sourceUrl;

          if (source.mediaItemUrl !== undefined) {
            sourceUrl = source.mediaItemUrl;
          }

          return await createRemoteFileNode({
            url: encodeURI(sourceUrl), // if encoding is unnecessary just replace with source.sourceUrl
            store,
            cache,
            createNode,
            createNodeId,
            reporter,
          });
        },
      },
    },
  });
};

For the query we now have to care about the new structure of featuredImage. Every featuredImage node contains a nested node structure, which was absent from my previous example:

export const query = graphql`
  query ArtistProfileQuery($id: ID!) {
    wp {
      artist(id: $id) {
        featuredImage {
          node { // THIS IS THE NEW NESTED NODE STRUCTURE
            sourceUrl
            altText
            imageFile {
              childImageSharp {
                fluid(
                  maxWidth: 2000
                  maxHeight: 1000
                  cropFocus: ATTENTION
                  grayscale: true
                ) {
                  ...GatsbyImageSharpFluid_withWebp
                  srcSet
                }
              }
            }
          }
        }
      }
    }
  }
`;

This also means that any previous references to for example data.wp.featuredImage.imageFile.childImageSharp.fluid should be changed to contain the node so that it becomes data.wp.featuredImage.node.imageFile.childImageSharp.fluid. The references might contain a data prefix as in my example, but depends on your particular setup.

I hope this was of any assistance to you both. If that was not the case do not hesitate to reach out once again.

@omattman if you omit sourceUrl from your query, do you still get an object for imageFile?

@antoinerousseau just leave it as url: source.sourceUrl

@omattman that's not what I mean, and I don't even use wordpress so my code is different, what I mean is:
in your example, can you please try removing/commenting out sourceUrl from the GraphQL query, and if so, do you still get an object for imageFile? It should be independent but in my code if I don't select the original field, the generated sharp image is undefined, which is weird.

@antoinerousseau this would be a new issue concerning your setup and I wouldn't have any chance in providing an option for you since I have no insights to your setup. My updated code is concerned with WordPress and the thread should be related to that as well.

@omattman I know but I was just asking for a favor for you to try selecting only imageFile but not sourceUrl in your GraphQL query and see if it works in your project but never mind

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mikestopcontinues picture mikestopcontinues  路  3Comments

theduke picture theduke  路  3Comments

Oppenheimer1 picture Oppenheimer1  路  3Comments

andykais picture andykais  路  3Comments

hobochild picture hobochild  路  3Comments