Next.js > Managing images

Managing images

One of the major advantages of using DatoCMS instead of any other content management systems is its responsiveImage query, which returns pre-computed image attributes that will help you setting up responsive images in your frontend without any additional manipulation.

To make it even easier to offer responsive, progressive images on your projects, we offer a package called react-datocms that exposes two components pairing perfectly with the responsiveImage query: <Image /> and <RSCImage />.

Our solution offers the same advantages as using the Next.js Image component, with the added benefit of having beautiful low-quality image placeholders (LQIP) in base64 format embedded directly within the page, without any additional request to be made by the browser or server:

To take advantage of it, install the react-datocms package:

npm install react-datocms

Then, inside your page, feed content coming from a responsiveImage query directly into the <Image /> component:

import { Image as DatoImage, RSCImage as DatoSRCImage } from "react-datocms";
import { performRequest } from '../lib/datocms';
const PAGE_CONTENT_QUERY = `query HomePage($limit: IntType) {
allBlogPosts(first: $limit) {
id
title
coverImage {
responsiveImage(imgixParams: { fit: crop, w: 300, h: 300, auto: format }) {
sizes
src
width
height
alt
title
base64
}
}
}
}`;
export default async function Home() {
const pageContent = await performRequest({
query: PAGE_CONTENT_QUERY,
variables: { limit: 10 },
});
return (
<div>
{data.allBlogPosts.map(blogPost => (
<article key={blogPost.id}>
{/* client component with custom lazy-loading via IntersectionObserver */}
<DatoImage data={blogPost.coverImage.responsiveImage} />
{/* server component, uses native loading="lazy" */}
<DatoSRCImage data={blogPost.coverImage.responsiveImage} />
<h2>{blogPost.title}</h2>
</article>
))}
</div>
);
}

<SRCImage /> vs <Image />

Even though their purpose is the same, there are some significant differences between these two components. Depending on your specific needs, you can choose to use one or the other:

  • <SRCImage /> is a React Server Component, so it can be rendered and optionally cached on the server. It doesn't create any JS footprint. It generates a single <picture /> element and implements lazy-loading using the native loading="lazy" attribute. The placeholder is set as the background to the image itself. Be careful: the placeholder is not removed when the image loads, so it's not recommended to use this component if you anticipate that the image may have an alpha channel with transparencies.

  • <Image /> is a Client Component. Since it runs on the browser, it has the ability to set a cross-fade effect between the placeholder and the original image, but at the cost of generating more complex HTML output composed of multiple elements around the main <picture /> element. It also implements lazy-loading through IntersectionObserver, which allows customization of the thresholds at which lazy loading occurs.

We recommend that you delve deeper into the topic in the documentation of the components themselves.