gatsbyjs / gatsby

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

[gatsby-source-graphql] No localFile on featuredImage from Wordpress #16158

Closed omattman closed 4 years ago

omattman commented 5 years ago

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?

fabianderijk commented 4 years ago

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

omattman commented 4 years ago

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 👍.

h0rhay commented 4 years ago

@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 🙏

antoinerousseau commented 4 years ago

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

omattman commented 4 years ago

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.

antoinerousseau commented 4 years ago

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

omattman commented 4 years ago

@antoinerousseau just leave it as url: source.sourceUrl

antoinerousseau commented 4 years ago

@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.

omattman commented 4 years ago

@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.

antoinerousseau commented 4 years ago

@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

hesta-inrsaurabh commented 6 months ago

Hello @omattman

I am using the above approach same like on https://www.gatsbyjs.com/docs/how-to/images-and-media/preprocessing-external-images/

Two issues I am facing

  1. It takes lots of time to have production build
  2. Some time some image do not have any base64 images

It is a very old project so can not upgrade to the latest gatsby-source-wordpress, I have to use gatsby-soruce-graphql.

Any suggestion on this?

Thank You.

omattman commented 6 months ago

@hesta-inrsaurabh sorry, I won't be able to be of any help here as I'm not involved with the Gatsby framework any longer.

hesta-inrsaurabh commented 6 months ago

@hesta-inrsaurabh sorry, I won't be able to be of any help here as I'm not involved with the Gatsby framework any longer.

Thank you @omattman for responding, I am checking at my end progressing slowly 😄