How to render image from IPFS using Next.js

I’m quite new in web3 and IPFS, trying to understand that technologies using a course with NFT Marketplace but it’s 2 years old, so I found some difficulties in case of deprecation ipfs-http-client: so I switch to kubo-rpc-client which has a quite similar functionality, and trying to use infura with that guide.

I solved the problem with loading an image on my dedicated gateway:

I have an example:

But I can’t render that image cuz of my error in Next.js app:

The requested resource isn’t a valid image for received application/octet-stream`

I also tried MediaRenderer from @thirdweb-dev/react using this guide

with url like ipfs://, for example:


Also using MediaRenderer I found out that image requested from

like that

but still on my Next.js app it has a white placeholder instead of an actual image.

I have a really simple question. How to render the image from file which stores on

Can’t find any solution for that in 2023


okay, I found out that problem was on my side,
i’m using client side to send file on my api to get a secrets from .env to upload it on ipfs and didn’t handle files well, it worked like uploading a files not an images, then I changed the strategy to use formdata to send a file like this:

  const uploadToIPFS = async (file: File) => {
    try {
      const data = new FormData();
      data.append("name", "Image Upload");
      data.append("file_attachment", file);
      const response = await"/api/ipfs", data, {
        headers: {
          "Content-Type": "multipart/form-data;",
    } catch (e) {
      console.error(`Error uploading file to IPFS: ${e}`);

and after that in pages/api/ipfs.ts

import { NextApiRequest, NextApiResponse } from "next";
import { create } from "kubo-rpc-client";
import { createReadStream } from "fs";
import { IncomingForm, File } from "formidable";

const {
} = process.env;

const auth = `Basic ${Buffer.from(

const client = create({
  host: "",
  port: 5001,
  protocol: "https",
  headers: {
    authorization: auth,
export const config = {
  api: {
    bodyParser: false,

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  try {
    if (req.method !== "POST") {
      return res.status(405).json({ error: "Method Not Allowed" });

    const form = new IncomingForm();

    form.parse(req, async (err, fields, files) => {
      if (err) {
        console.error(`Error parsing form data: ${err}`);
        return res.status(500).json({ error: "Internal Server Error" });

      const fileAttachment = files.file_attachment as File[];

      if (!fileAttachment) {
        return res
          .json({ error: "File not provided in the request" });

      const added = await client.add(
      const url = `${added.cid}`;

      res.status(200).json({ url });
  } catch (error) {
    console.error(`Error handling file upload: ${error}`);
    res.status(500).json({ error: "Internal Server Error" });

so it helps me to handle images well, now when i upload an image using kubo-rpc-client, i get the correct CID to an image, not a file, so i can easily use MediaRenderer now from thirdweb or use a common html image tag or Image from ‘next/image’


Hey @unsleeping , thanks for letting us know and for the details provided. Should you face other issues let us know and we’ll try to help.