51
Blurred image placeholder with Next.js image and Cloudinary
Most of the time, we don't want to manage image optimizations ourselves. Libraries such as Next.js/image are handy to deal with responsive images. In addition to Next.js image, I often use Cloudinary, which is a media management service.
Two key benefits:
Two key benefits:
Next.js provides excellent integration with Cloudinary. For example, we can use the following next.config.js file.
const cloudinaryBaseUrl = `https://res.cloudinary.com/${process.env.CLOUDINARY_CLOUD_NAME}/image/upload/`;
module.exports = {
images: {
loader: "cloudinary",
path: cloudinaryBaseUrl,
},
};
where the CLOUDINARY_CLOUD_NAME env variable contains our cloudinary cloud name.
We're ready to build a basic app to display an image using next/image and Cloudinary. Here's what a React code would be like:
function Home({ exampleImage }) {
return (
<div className={styles.container}>
<main className={styles.main}>
<h1 className={styles.title}>Blurred image placeholder</h1>
<h2 className={styles.subtitle}>with Next.js image and cloudinary</h2>
<div className={styles.imagewrapper}>
<Image
src={exampleImage.src}
alt="Example"
width="1920"
height="1280"
layout="responsive"
quality="75"
sizes="60vw"
/>
</div>
</main>
</div>
);
}

Let's try to add a blurred image placeholder. Next/image provides two properties: placeholder and blurDataURL. We will rely on Cloudinary to get a low-quality, blurred picture. It leads to the following function to generate a base64 encoded data URL:
export async function getBase64ImageUrl(imageId: string): Promise<string | undefined> {
const response = await fetch(`${process.env.CLOUDINARY_BASE_URL}w_100/e_blur:1000,q_auto,f_webp${imageId}`);
const buffer = await response.arrayBuffer();
const data = Buffer.from(buffer).toString('base64');
return `data:image/webp;base64,${data}`;
}
Finally, we have to generate the data URL at compile-time. With Next.js, it's pretty straightforward by implementing the getStaticProps function:
export async function getStaticProps() {
const imageSrc = process.env.CLOUDINARY_EXAMPLE_IMAGE_SRC;
if (!imageSrc) {
throw new Error('Missing CLOUDINARY_EXAMPLE_IMAGE_SRC env variable');
}
const blurDataUrl = await getBase64ImageUrl(imageSrc);
return {
props: {
exampleImage: {
src: imageSrc,
blurDataUrl: blurDataUrl,
},
},
};
}
where the CLOUDINARY_EXAMPLE_IMAGE_SRC env variable contains our cloudinary image id.
So here's the final version of the React code:
function Home({ exampleImage }: InferGetStaticPropsType<typeof getStaticProps>) {
return (
<div className={styles.container}>
<main className={styles.main}>
<h1 className={styles.title}>Blurred image placeholder</h1>
<h2 className={styles.subtitle}>with Next.js image and cloudinary</h2>
<div className={styles.imagewrapper}>
<Image
src={exampleImage.src}
alt="Example"
width="1920"
height="1280"
layout="responsive"
quality="75"
sizes="60vw"
placeholder="blur"
blurDataURL={exampleImage.blurDataUrl}
/>
</div>
</main>
</div>
);
}
You can find the source code on Github.
This has been helpful for me in my projects. Hopefully it helps you as well.
This has been helpful for me in my projects. Hopefully it helps you as well.
51