Best practices for using image sizes in React projects with Sanity.io

3 replies
Last updated: May 21, 2020
Hi people,For those of you who use
imageUrlFor(buildImageObj(node.mainImage))...
how do you ensure to download a proper size of image for the current view port?

I have a code like

<img 
    src={imageUrlFor(buildImageObj(node.mainImage))
                      .auto('format')
                      .width(1000)
                      .url()} 
/>
Instead of
1000
, what do you do? Do you use JavaScript to get window width and calculate the width of image you want to get? Or is there any other recommended practice?
AI Update

Great question! The best practice for responsive images from Sanity is to use the native HTML srcset and sizes attributes rather than calculating widths with JavaScript. Here's the recommended approach:

Using srcset for Responsive Images

Instead of setting a single fixed width, generate multiple image URLs at different sizes and let the browser choose the most appropriate one:

function ResponsiveImage({image}) {
  return (
    <img 
      src={imageUrlFor(buildImageObj(image))
        .width(800)
        .url()}
      srcSet={[
        `${imageUrlFor(buildImageObj(image)).width(400).url()} 400w`,
        `${imageUrlFor(buildImageObj(image)).width(800).url()} 800w`,
        `${imageUrlFor(buildImageObj(image)).width(1200).url()} 1200w`,
      ].join(', ')}
      sizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px"
      alt={image.alt || ''}
    />
  )
}

Key Benefits

  1. Browser-native: The browser automatically selects the best image based on viewport size and device pixel ratio
  2. Performance: You're reusing cached transformations across your site
  3. No JavaScript needed: Works even if JS fails to load
  4. Future-proof: Browsers can make smarter decisions as they evolve

The sizes Attribute

The sizes attribute tells the browser how wide the image will be displayed at different breakpoints. This helps it choose from your srcSet options. Adjust these values based on your actual layout:

  • (max-width: 600px) 400px - On small screens, image displays at 400px
  • (max-width: 1200px) 800px - On medium screens, 800px
  • 1200px - Default for larger screens

Important Note

As mentioned in the Sanity documentation on presenting images, reusing the same image transformations across your site ensures cached assets are used effectively, which is much better for performance than dynamically calculating unique widths.

Avoid using JavaScript to calculate viewport width and generate unique image URLs on every render - this defeats Sanity's CDN caching and can lead to usage overages.

Hey
user S
I’ve used something like that on a project
 <picture>
        <img
          style={{ width: "100%" }}
          srcSet={`
            ${urlFor(node.asset).width(320)} 320w,
            ${urlFor(node.asset).width(480)} 480w,
            ${urlFor(node.asset).width(800)} 800w
          `}
          sizes={`
            (max-width: 320px) 280px,
            (max-width: 480px) 440px,
            800px
          `}
          src={urlFor(asset)}
        />
      </picture>
user T
Oh, I didn't think of that. I'm not very good with images 😅 Thanks for the tip!
I got this snippet straight from a codesandbox, but I can’t find the link 🤔 I tend to prefer this solution to GatsbyImage.

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?