Projects
Services
Migration
Blog
Alt textAlt text

The best Next.js & Sanity Image component

Reading Time

4 min read

Published on

June 9, 2023

Author

Jono

Jono

We'll keep it short and sweet.

This is the ideal Next Sanity Image. You may not like it, but this is what peak image performance looks like.
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> ); };

So let's start by breaking down what each bit does, why it's useful, and why you're not going to break your entire website by trying to reference an image that doesn't exist within the preview.

getImageDimensions

I'd put a fairly hefty bet on the fact you haven't seen this before. It's an absolute banger of a utility library that allows you to pull dimensions from an image.

Why is that useful? Well because one of the main features of using Next/Image is to avoid something called Cumulative Layout Shift. In short, that's the thing when you go on a website and it shifts and you end up clicking on a crappy ad instead of what you wanted.

blurDataURL

You've all seen those lovely blur up effects on Next/Image, so we thought we'd build something identical using the @sanity/image-url. This essentially loads a much smaller version first and with added blur, makes it look elegant. Then moves onto the higher quality version when loaded

Sizes="..."

This is pretty cool if you haven't seen this before. This is Next.js way of handling the different sizes for the different screen sizes. Essentially this is saying:

(max-width: 768px) 100vw

Up to a size of 768px, the maximum size will be 100% width of the screen. This means that when you're on a mobile or small tablet. The maximum size rendered will be the full width of that screen (as you mostly stretch images to the size of the screen in responsive views).

See below for how it looks on mobile - can you see how the image is nearly 100% of the width of the screen?

Image on mobile screens

(max-width: 1200px) 50vw

This on the other hand is saying that below 1200px, the image will be a maximum of 50vw e.g. if the screen is 1000px wide, at most the image will be 500px.

The reason for the difference in change is that instead of the image being 100% width, we now stack the image on the right, and the text on the left.

Take a look at this now, it makes sense right?

Image on the right, text on the left showing the screen on large tablet, small desktop mode

40vw

So everything above 1200px is now going to be at max 40vw. That's the easiest one to get. The reason for doing so is that the container progressively takes up less and less of the screen real estate and is going to probably be less than 40% of the overall size.

Again, pretty clever, and works like a charm

The image and text showing how it takes up less than 40% of the screen real estate above 1200px

Aspect Ratio & Cumulative Layout Shift (CLS)

Aspect ratio (the proportional relationship between an image's width and height) is an essential aspect of web page design. Google highly values the optimal use of aspect ratio and static heights & widths, according to Cumulative Layout Shift (CLS) – a metric measuring the surprise positional changes of contents during page load. Heavy CLS often distorts user experience as it results in accidental clicks or difficulty in reading. If you want to actually see exactly how good/bad your current CLS there's a great tool here

Image Rendering Modes

There are typically four common ways to handle image displaying, especially considering responsiveness:

1. `width: auto` and `height: auto`: Both preserve the original aspect ratio within the parent container's dimensions. However, they may not cover its full extent.

2. `width: 100%` and `height: auto`: Forces the image to span the full width of its parent, self-adjusting its height to retain the original proportion.

3. `objectFit: "cover"`: Corresponding CSS's `background-size: cover`, it scales the image to cover its parent, potentially cropping parts due to aspect ratio differences.

4. Static `width` and `height` values: Ignores the parent size and original aspect ratio, rigorously sets the image's height and width.

Any other parts?

Well, that's about it, it's using the latest version of Next/Image so be aware that there have been significant changes over the years, but as for the latest and greatest, this is what Roboto is using.

Get in touch

Any questions?

Look, we were being a little hyperbolic by saying it's the best Next.js & Sanity image, but how are we supposed to keep up with buzzfeed's AI driven blog posts. We need to beat clickbait with clickbait.

But in all seriousness, if you have any issues with building one of these yourself, get us in for a couple days of consulting and we can help you trim the fat off of any project and get things blazing fast 🔥

Services

Legal

Like what you see ?

Sign up for a 30 min chat and see if we can help

© 2024 Roboto Studio Ltd - 11126043

Roboto Studio Ltd,

86-90 Paul Street,

London, EC2A 4NE

Registered in England & Wales | VAT Number 426637679