Blob in NextJs for images

Viewed 6866

I need to add image url as a blob using technologies like next and node as a backend.

First I try use simple way to create what I need.

const ErrorMsg = (props) => {
    const image = "/logo.png";
    const blob = new Blob([image], {type: 'image/png'})
    const img = URL.createObjectURL(blob);
    return (
        <>
            <div className={classes.errorMsg}>
                <img src={img} />
            </div>
        </>
    )
}

First time I don't know how but it works like in here image not showing but also webpack not give an error.

I forget how I it breaked but I got this error after I use some code manipulations trying to fix it.

Blob is not defined.

I thought need an extra package so I install node-blob

import Blob from "node-blob";

const ErrorMsg = (props) => {
    const image = "/logo.png";
    const blob = new Blob([image], {type: 'image/png'})
    const img = URL.createObjectURL(blob);
    return (
        <>
            <div className={classes.errorMsg}>
                <img src={img} />
            </div>
        </>
    )
}

So now I getting this error URL.createObjectURL is not a function

3 Answers

Both URL and Blob is part of the Web API, thus not available on the server side of your app.

If you need to use both of them, you should use them inside a useEffect, which will only be triggered client side.

import { useState, useEffect } from 'react';

const ErrorMsg = (props) => {
    const image = "/logo.png";
    const [src, setSrc] = useState(''); // initial src will be empty

    useEffect(() => {
      const blob = new Blob([image], {type: 'image/png'})
      const img = URL.createObjectURL(blob);

      setSrc(img); // after component is mount, src will change
    }, []);

    return (
        <>
            <div className={classes.errorMsg}>
                <img src={src} />
            </div>
        </>
    )
}

That said, is there a reason you need to create a Blob? You can serve static files for Next.js by storing them under a folder named public, as described here.

the better way is that you import your component with dynamic import :

import dynamic from 'next/dynamic';

const MyComponentNoSSR = dynamic(() => import('./MyComponentNoSSR'), {
  ssr: false,
});
Related