4

At the top of my gatsby blog (a react component) I have a function that gets a url's extension, and based on whether it's an image or a video it returns a line of html like so:

  const printPicOrVid = function(myUrl) {
    let fileExt =
      myUrl.substring(myUrl.lastIndexOf(".") + 1, myUrl.length) || myUrl
    if (fileExt === "jpg" || fileExt === "png" || fileExt === "gif") {
      return '<img src="https:' + myUrl + '" />'
    } else if (fileExt === "mp4") {
      return '<video src="https:' + myUrl + '"></video>'
    }
  }

which successfully returns a string of something like <img src="https://contentful.com/whatever/image.jpg" />

in my return part of the react page I have:

{edge.node.heroImage && printPicOrVid(edge.node.heroImage.file.url)}

which is saying: if the heroImage from contentful exists, then return the jpg or mp4 html. The problem is, I just get a string of the HTML printed to the page, not the html rendering an actual image or video like intended.

have a feeling the answer here is dangerously set inner HTML, but not sure how to implement. Any help much appreciated, thanks.

1
  • 2
    Actually yeah, Ismael's is a better idea. Just return the JSX img or video element, and make the src the dynamic string, rather than the whole element a string Commented Jan 22, 2020 at 0:00

2 Answers 2

8

When returning JSX in a function, you should just plainly return the JSX element you want. So you'd write return <div/> instead of return '<div/>'. So:

return '<img src="https:' + myUrl + '" />'

Should be

return <img src={"https:" + myUrl} />

Otherwise you'd return a string instead of JSX. Same in the other return statement, which should be:

return <video src={"https:" + myUrl}></video>
Sign up to request clarification or add additional context in comments.

Comments

2

You need to return a <div /> with attribute dangerouslySetInnerHTML set to {{ __html: printPicOrVid(edge.node.heroImage.file.url) }}.

Full code:

{edge.node.heroImage && <div dangerouslySetInnerHTML={{ __html: printPicOrVid(edge.node.heroImage.file.url) }} />}

1 Comment

Thank you! I figured I should avoid dangerouslySetInnerHTML if possible though so I went with Ismael's solution, appreciate the answer though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.