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.


This topic was automatically closed after 30 days. New replies are no longer allowed.