cloudinary-community / gatsby-transformer-cloudinary

Use Cloudinary images with gatsby-image for high performance and total control!
https://gatsby-transformer-cloudinary.netlify.app/
MIT License
69 stars 28 forks source link

Cannot query gatsbyImageData via Cloudinary app on Contentful #238

Open jasloe opened 1 year ago

jasloe commented 1 year ago

I am trying to use this project to transform Cloudinary-hosted images passed through Contentful with unfortunately mixed results.

In short, I have a Contentful environment with a content type ("Artwork"). The content type includes a JSON Object field ("cloudinaryImage") connected to the Contentful Cloudinary app. The app is configured correctly and returning data.

gatsby-config.js contains:

    {
      resolve: `gatsby-source-cloudinary`,
      options: {
        cloudName: [redacted],
        apiKey: [redacted],
        apiSecret: [redacted],
        tags: true,
        context: true,
        prefix: [redacted],
      },
    },
  {
      resolve: `gatsby-transformer-cloudinary`,
      options: {
        transformTypes: [`CloudinaryMedia`, `contentfulArtworkCloudinaryImageJsonNode`],
        defaultTransformations: ['c_fill', 'g_auto', 'q_auto'],
      },
    },
    `gatsby-plugin-image`,

template/artwork.js contains (simplified for brevity):

const Artwork = ({ data }) => (
  <>
    {data.contentfulArtwork.id}
    {data.contentfulArtwork.title}
    {data.contentfulArtwork.cloudinaryImage.map((image) => (
      <div key={image.id}>
        {image.id}
        <GatsbyImage image={getImage(image)} alt="testing" />
      </div>
    ))}
  </>
);

export default Artwork;

export const artworkQuery = graphql`
  query ($ArtworkId: String!) {
    contentfulArtwork(id: { eq: $ArtworkId }) {
      id
      title
      __typename
      cloudinaryImage {
        id
        __typename
        gatsbyImageData(width: 200, height: 200)
      }
    }
  }
`;

Looking at the console output, gatsbyImageData returns null...

{
    "id": [redacted],
    "title": "Example",
    "__typename": "ContentfulArtwork",
    "cloudinaryImage": [
        {
            "id": [redacted],
            "__typename": "contentfulArtworkCloudinaryImageJsonNode",
            "gatsbyImageData": null
        },
        {
            "id": [redacted],
            "__typename": "contentfulArtworkCloudinaryImageJsonNode",
            "gatsbyImageData": null
        }
    ]
}

...and throws an error:

[gatsby-plugin-image] Missing image prop

Looking at the stack trace, the error happens here:

export const GatsbyImage: FunctionComponent<GatsbyImageProps> = memo(
  function GatsbyImage(props) {
    if (!props.image) {
      if (process.env.NODE_ENV === `development`) {
        console.warn(`[gatsby-plugin-image] Missing image prop`)
      }

      return null
    }

    if (!gatsbyImageIsInstalled() && process.env.NODE_ENV === `development`) {
      console.warn(
        `[gatsby-plugin-image] You're missing out on some cool performance features. Please add "gatsby-plugin-image" to your gatsby-config.js`
      )
    }

    return createElement(GatsbyImageHydrator, props)
  }
)

GatsbyImage.propTypes = propTypes
GatsbyImage.displayName = `GatsbyImage`

Not sure where to go with this. I'm able to query and render CloudinaryMedia to the browser without any problem. gatsby-plugin-image is working fine with both Contentful-hosted and locally hosted images.

jasloe commented 1 year ago

Just replicated this issue on a clean Gatsby codebase, a new Contentful space, and a new Cloudinary environment.

Confirming that this works as expected:

query MyQuery {
  allCloudinaryMedia {
    nodes {
      gatsbyImageData
    }
  }
}

But this doesn't:

query MyQuery {
  contentfulArtwork {
    images {
      gatsbyImageData
    }
  }
}

returns...

{
  "data": {
    "contentfulArtwork": {
      "images": [
        {
          "gatsbyImageData": null
        }
      ]
    }
  },
  "extensions": {}
}

My environment:

  System:
    OS: macOS 12.6.3
    CPU: (12) x64 Intel(R) Xeon(R) CPU E5-1650 v2 @ 3.50GHz
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 18.15.0 - ~/.nvm/versions/node/v18.15.0/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v18.15.0/bin/yarn
    npm: 9.5.0 - ~/.nvm/versions/node/v18.15.0/bin/npm
  Browsers:
    Firefox: 89.0.2
  npmPackages:
    gatsby: ^5.11.0 => 5.11.0
    gatsby-plugin-image: ^3.11.0 => 3.11.0
    gatsby-plugin-sharp: ^5.11.0 => 5.11.0
    gatsby-source-cloudinary: ^0.5.1 => 0.5.1
    gatsby-source-contentful: ^8.11.0 => 8.11.0
    gatsby-transformer-cloudinary: ^4.4.0 => 4.4.0
    gatsby-transformer-sharp: ^5.11.0 => 5.11.0
  npmGlobalPackages:
    gatsby-cli: 5.7.0
olavea commented 1 year ago

I'll ask my senior dev to send you an email. I'm sure she would like us to have a chat with you about this problem. It is relevant to our work. 😺 👍

raae commented 1 year ago

The shape of contentfulArtworkCloudinaryImageJsonNode does not match the shape that the transformer plugin expects, but you may connect the sourced CloudinaryMedia to your contentfulArtworkCloudinaryImageJsonNode nodes.

exports.createSchemaCustomization = async ({ actions }) => {
  actions.createTypes(`
    type contentfulArtworkCloudinaryImageJsonNode implements Node {
      cloudinaryMedia: CloudinaryMedia @link(by: "publicId", from: "public_id")
    }
  `);
};

Then you'd need to add one level to get the gatsbyImageData query, doing

       cloudinaryMedia {
          gatsbyImageData(width: 200)
        }
AminPainter commented 1 year ago

Try this: https://github.com/cloudinary-devs/gatsby-transformer-cloudinary/issues/246#issuecomment-1794309309

raae commented 1 year ago

Thank you @AminPainter !

raae commented 9 months ago

I would be forever grateful if you tested the newest beta jasloe. It adds support by letting you configure the mapping of data.

yarn add gatsby-transformer-cloudinary@4.6.0-beta.1

Take a look at the documentation and let me know how it goes so I may improve if needed.

raae commented 5 months ago

@jasloe have you been able to test the 4.6.0-beta.1? Looking to make this a current version, but would love an external test before I do.