For anybody that’s looking at building Next.js websites with a headless content management system, we have a nice utility for handling images. Ours is specific to Sanity, but with a little prompt from something like Cursor this could very easily be translated to pretty much any headless content management systems. Hell, we might even do it as an article for the free SEO.
Without further ado here’s the code, go steal it:
import { ReactElement } from 'react';
import Image from 'next/image';
import { getImageDimensions } from '@sanity/asset-utils';
import { urlFor } from '~/lib/sanity';
export const IdealImage = ({ image }): ReactElement => {
const alt = image?.alt ?? "image broke";
const dimensions = getImageDimensions(image);
return (
<div>
...
{image?.asset && (
<Image
src={urlFor(image).url()}
alt={alt}
width={dimensions.width}
height={dimensions.height}
placeholder="blur"
blurDataURL={urlFor(image).width(24).height(24).blur(10).url()}
sizes="
(max-width: 768px) 100vw,
(max-width: 1200px) 50vw,
40vw"
/>
)}
...
</div>
);
};
If you want to have a deeper dive as to why we’ve used the sizes that we’ve used, you can read the full article here.
Some cliffnotes -
- We use the sizes because our image goes from full width, to half width, to slightly less than half width on larger desktop
- There’s some space to use blurHash and lqip but we kept it simple so most folks can cut and paste this in and it would work. Read more for this here
- There are image libraries such as this one, but we just like Next/Image for the vibes, so we use that
- You also need the
{image?.asset && (
or else the image will break in preview if you haven’t set an image source.