Search code examples
reactjsgatsbygatsby-plugin

gatsby-source-medium thumbnail image not showing


I'm using gatsby in my react project, to show my medium, articles inside the project.

below is my graphql query for that.

const BlogPost = () => {
  const blogMediumQueryData = useStaticQuery(graphql`
    query Medium {
      allMediumPost(sort: { fields: [createdAt], order: DESC }) {
        edges {
          node {
            id
            title
            uniqueSlug
            createdAt(formatString: "MMM YYYY")
            virtuals {
              previewImage {
                imageId
              }
            }
            author {
              name
            }
          }
        }
      }
    }
  `)

  const blogs = blogMediumQueryData.allMediumPost.edges
return (
    <Blog
        image={blog.node.virtuals.previewImage.imageId}
        title={blog.node.title}
        date={blog.node.createdAt}
        author={blog.node.author.name}
        path={blog.node.uniqueSlug}
     />
  )

this gives me the preview image ID. And I'm passing it to the child component as a prop. But when I try to show the image with the Img component from gatsby, the Image is not showing.

Here is my code for the child component

import React from "react"
import { Link } from "gatsby"
import { slugify } from "../utils/utilityFunctions"
import Image from "../elements/image"

const Blog = ({ image }) => {
  return (
    <div className="content-block">
      <div className="post-thubnail">
        {image && (
          <Link to={postUrl} target='blank'>
            <Image src={image} alt={title} />
          </Link>
        )}
      </div>
  )
}
export default Blog

Here is the code for the Image component

import React from "react";
import Img from "gatsby-image";

const NonStretchedImage = props => {
    let normalizedProps = props
    normalizedProps = {...normalizedProps.fluid, aspectRatio: 1}
    let alignment;
    if(props.align === 'right'){
        alignment = '0 0 0 auto'
    } else if(props.align === 'left'){
        alignment = '0 auto 0 0'
    }else{
        alignment = '0 auto'
    }

    if (props.fluid && props.fluid.presentationWidth) {
        normalizedProps = {
            ...props,
            style: {
                ...(props.style || {}),
                maxWidth: props.fluid.presentationWidth,
                margin: alignment, 
            },
        }
    }

    return <Img {...normalizedProps} />
}

export default NonStretchedImage;

This is my first project with gatsby and graphql. Is there are anything that I have missed or is there anything that I'm doing wrong?

Thanks in advance


Solution

  • A few caveats that I guess will put you on the track to fix the issue.

    node, in the GraphQL query is an array, in the same way, I guess that virtuals it is. Check and test the response in the localhost:8000/___graphql playground.

    So assuming that your query works as expected, your code should look like:

    const BlogPost = () => {
      const blogMediumQueryData = useStaticQuery(graphql`
        query Medium {
          allMediumPost(sort: { fields: [createdAt], order: DESC }) {
            edges {
              node {
                id
                title
                uniqueSlug
                createdAt(formatString: "MMM YYYY")
                virtuals {
                  previewImage {
                    imageId
                  }
                }
                author {
                  name
                }
              }
            }
          }
        }
      `)
    
      const blogs = blogMediumQueryData.allMediumPost.edges
    return (
        <Blog
            image={blog.node[0].virtuals.previewImage.imageId}
            title={blog.node[0].title}
            date={blog.node[0].createdAt}
            author={blog.node[0].author.name}
            path={blog.node[0].uniqueSlug}
         />
      )
    

    Alternatively, you can loop through the array of nodes and use your previous Blog component since it will get each iterable variable.

    I don't think your Image component be able to render a gatsby-image only using the imageId. Gatsby needs a bunch of data (given by its transformers and sharps) to render the image, not using an identifier but series of fields (that's why it usually renders query fragments, noted by ...). Your image component, in the end, should render something like:

    <img src={`https://medium.com/${blog.node[0].virtuals.previewImage.imageId}`}
    

    Based on: https://blog.devgenius.io/how-to-scrap-your-medium-articles-with-gatsby-js-f35535ebc09d

    So summarizing, gatsby-source-medium by itself doesn't provide enough data to use gatsby-image or gatsby-image-plugin plugins so I'm afraid you won't be able to use the Img component. You have to use the standard img tag.