How can I get the image url from IPFS info in React.js?

Viewed 15268

I've gotten this IPFS info such as "/ipfs://QmQqzMTavQgT4f4T5v6PWBp7XNKtoPmC9jvn12WPT3gkSE" as API response.

I want to display this file(image) on my page, but I can't find out the correct solution.

How can I get the image URL from this info in react app?

Please help with my concern.

5 Answers

If you're using js-ipfs, you can retrieve the image over IPFS, and display it:

/** Uses `URL.createObjectURL` free returned ObjectURL with `URL.RevokeObjectURL` when done with it.
 * 
 * @param {string} cid CID you want to retrieve
 * @param {string} mime mimetype of image (optional, but useful)
 * @param {number} limit size limit of image in bytes
 * @returns ObjectURL
 */
async function loadImgURL(cid, mime, limit) {
    if (cid == "" || cid == null || cid == undefined) {
        return;
    }
    for await (const file of ipfs.get(cid)) {
        if (file.size > limit) {
            return;
        }
        const content = [];
        if (file.content) {
            for await(const chunk of file.content) {
                content.push(chunk);
            }
            return URL.createObjectURL(new Blob(content, {type: mime}));
        }
    }
}

Then you can display it with something like:

<body>
<img id="myImage" />
<script>
async function setImage() {
    // just an example, make sure to free the resulting ObjectURL when you're done with it
    //
    // if your CID doesn't work, try this one: Qmcm32sVsMYhURY3gqH7vSQ76492t5Rfxb3vsWCb35gVme
    // that's a popular CID, which should resolve every time
    document.getElementById("myImage").src = await loadImgURL("QmQqzMTavQgT4f4T5v6PWBp7XNKtoPmC9jvn12WPT3gkSE", "image/png", 524288);
}
setImage();
</script>
</body>

The big advantage of this is you're using the IPFS network itself, and not relying on a public HTTP gateway (the recommended way).

You can do something like that:

tokenURI.replace("ipfs://", "https://ipfs.io/ipfs/");

One thing to note here about fetching images from IPFS that I think isn't being discussed sufficiently in these answers is that you will need to either

  1. Run your own node of IPFS, or
  2. Get a hosted IPFS node through a service like Infura

I have spent a little bit of time working through this in the last couple of days, and it will always come back to you having to have direct access to your own node.

There are "Gateways," which are nodes hosted by the community, and you can read more about them in the IPFS docs here: https://docs.ipfs.io/concepts/ipfs-gateway/#limitations-and-potential-workarounds

The thing with the gateways is that they are not meant to be relied upon for production sites, as you can see below. It's possible that there is some hosted node out there that somebody is giving out for free, but I doubt it, and you wouldn't want to rely on that anyways.

I think that other questions above have elaborated how you actually process the responses once you get it, but I wanted to cover this extra ground in my answer.

ipfs docs

let imgUrl = url?.slice(url.indexOf(":"),url?.lastIndexOf("/"));
let slice = url?.slice(url.lastIndexOf("/"),url?.length)
let renderURL = `https${imgUrl}.ipfs.dweb.link${slice}`;
console.log(renderURL);
Related