Next Cloudinary v6 now available! View Changelog

Guides
Placeholders

Display Placeholder While Image is Loading

CldImage wraps the Next.js Image component, thus giving us access to the placeholder API which can display an SVG image while the image itself is loading.

This helps for providing a great user experience, rather than an empty space, to help let the visitor know that image is loading.

To do this, we have several options:

  • placeholder="blur" coupled with a blurDataURL
  • placeholder="..." with the contents being a data URL

When working in the App Router, its currently recommended to wrap CldImage to make it easier to use in Server Components without having to opt an entire page in to a Client Component. Learn more

Blurred Images

To achieve a blurred image effect, we can first convert our Cloudinary image to a Data URL then pass it in to our CldImage component.

Mountains

Inside of the App Router, we can utilize server components to generate a data URL from our image.

Within a server component, gerate the Data URL with:

import { getCldImageUrl } from 'next-cloudinary';
 
const imageUrl = getCldImageUrl({
  src: '<Your Public ID>',
  width: 100, // Resize the original file to a smaller size
});
const response = await fetch(imageUrl);
const arrayBuffer = await response.arrayBuffer();
const buffer = Buffer.from(arrayBuffer);
const base64 = buffer.toString("base64");
const dataUrl = `data:${response.type};base64,${base64}`;

Then when rendering CldImage, utilize the dataUrl using placeholder and blurDataURL:

import { CldImage } from 'next-cloudinary';
 
<CldImage
  src="<Your Public ID>"
  width="600"
  height="400"
  alt="Decriptive text"
  placeholder="blur"
  blurDataURL={dataUrl}
/>

Shimmer

Similar to the example from the Next.js documentation, we can create a shimmer effect when our images are loading.

Example from: https://github.com/vercel/next.js/blob/canary/examples/image-component/pages/shimmer.tsx (opens in a new tab)

Mountains

Inside of the App Router, we can utilize server components to generate a data URL from our image.

Within a server component, gerate the Data URL with:

const shimmer = (w: number, h: number) => `
  <svg width="${w}" height="${h}" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <defs>
      <linearGradient id="g">
        <stop stop-color="#333" offset="20%" />
        <stop stop-color="#222" offset="50%" />
        <stop stop-color="#333" offset="70%" />
      </linearGradient>
    </defs>
    <rect width="${w}" height="${h}" fill="#333" />
    <rect id="r" width="${w}" height="${h}" fill="url(#g)" />
    <animate xlink:href="#r" attributeName="x" from="-${w}" to="${w}" dur="1s" repeatCount="indefinite"  />
  </svg>`
 
const toBase64 = (str: string) =>
  typeof window === 'undefined'
    ? Buffer.from(str).toString('base64')
    : window.btoa(str)
 
const dataUrl = `data:image/svg+xml;base64,${toBase64(shimmer(600, 400))}`;

Then when rendering CldImage, utilize the dataUrl using placeholder:

import { CldImage } from 'next-cloudinary';
 
<CldImage
  src="<Your Public ID>"
  width="600"
  height="400"
  alt="Decriptive text"
  placeholder={dataUrl}
/>

Learn More