5

Minimum Reproducible Example on Github


I'm trying to inject some images into my pages created from markdown. I'm trying to do this using ReactDomServer.renderToString()

const componentCreatedFromMarkdown = ({data}) => {
...    
    useEffect(() => {
        const injectDivs = Array.from(document.getElementsByClassName('injectDivs'))
        injectDivs.forEach((aDiv) => {
            aDiv.innerHTML = ReactDOMServer.renderToString(<Img fluid={data.allFile.edges[0].node.childImageSharp.fluid} />)
        }
    })
...
}

The img is showing as a black box, if I right click the image I can open it in a new tab, which shows the image as it is supposed to be.


enter image description here

Sam
  • 1,765
  • 11
  • 82
  • 176

3 Answers3

3

How I understand the problem

  • The image html is correctly inserted into the page

  • gatsby-image loads the lowest quality image and applies some inline styles. All that information is present in the html) This is done to enable the blur-up effect on the image for a better UX.

  • The client side code that would load a higher resolution image and remove the inline styles is never applied.

Useful diagnostic information

  • The function inside useEffect does not get run on the server-side, but rather on the client after the component has mounted. It's possible to verify this by adding a console.log statement inside the effect and seeing that it is logged on the browser's console.

Source of the problem

  • ReactDOMServer.renderToString() only builds the HTML that's required by a component, it then requires the component to be hydrated.

Direct fix

  • You can use ReactDOM.render to put the image on the page, given that the effect will execute client side. I have a PR showing that here.

Recommended approach

Hope that helps!

JuanCaicedo
  • 3,132
  • 2
  • 14
  • 36
0

I have faced this problem before with my first Gatsby project. The problem similar to this chat and the error image issue here.

If you replace GatsbyImageSharpFixed_withWebp_tracedSVG like they talked in spectrum chat above, or this is my current code for example, basically is related to WebP new image format.

export const query = graphql`
  query {
    allImageSharp {
      edges {
        node {
          fluid(maxWidth: 110) {
            aspectRatio
            originalName
            sizes
            src
            srcSet
            srcWebp
            tracedSVG
          }
        }
      }
    }
  }
`;

Hope this help.

ShinaBR2
  • 2,519
  • 2
  • 14
  • 26
0

I think the problem could be in the useEffect

const componentCreatedFromMarkdown = ({data}) => {

...    
    useEffect(() => {
        const injectDivs = Array.from(document.getElementsByClassName('injectDivs'))
        injectDivs.forEach((aDiv) => {
            aDiv.innerHTML = ReactDOMServer.renderToString(<MyComponent args={myArgs} />)
        }
    },[])
...
}

I think you should try to add useEffect(()=>{},[]), the second argument to refresh the image only when the component is mounted, without this the image will be refreshed each time.

Yoandry Collazo
  • 1,122
  • 9
  • 16
  • I posted a [Minimum Reproducible example on Github](https://github.com/stackoverflowsam93/gatsby-image-is-black). You're solution didn't fix it unfortunately. – Sam Jul 08 '20 at 01:31