At the top of my gatsby blog (a react ponent) 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=".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.
At the top of my gatsby blog (a react ponent) 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./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.
Share Improve this question edited Jan 22, 2020 at 0:08 Ismael Padilla 5,5865 gold badges25 silver badges37 bronze badges asked Jan 21, 2020 at 23:54 StephDStephD 3044 silver badges23 bronze badges 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 – Jayce444 Commented Jan 22, 2020 at 0:00
2 Answers
Reset to default 8When 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>
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) }} />}