Preventing image jank with Sanity images in Gatsby (gatsby-image vs @sanity/image-url)

9 replies
Last updated: Jan 28, 2026
how do I achieve this same result and avoid this content jankiness (image pushing down content) in Sanity? https://css-tricks.com/do-this-to-improve-image-loading-on-your-website/
I am currently editing
Blog with Gatsby
template but so far dumbfounded on how to solve this with sanity (gatsby-image seems to do it for you). Do I modify in this file here? https://github.com/ajmalafif/afif.dev/blob/develop/web/src/lib/image-url.js
or somehow I can achieve this “lazy-loading” effect by combining both
gatsby-image
and
sanity/image-url
? https://github.com/sanity-io/gatsby-source-sanity#fluid
AI Update

Looking at the CSS Tricks article you linked, it's about preventing content layout shift (CLS) when images load by reserving the proper space with aspect ratio. The good news is that gatsby-plugin-image handles this automatically when you use it with Sanity images through gatsby-source-sanity!

The modern approach with gatsby-source-sanity and gatsby-plugin-image gives you lazy loading, proper aspect ratios, and prevents content jank out of the box. Here's how to set it up:

Use the gatsbyImageData field in your GraphQL queries. This automatically includes dimensions and generates the proper placeholder:

import {GatsbyImage} from 'gatsby-plugin-image'

export const query = graphql`
  query {
    sanityPost {
      mainImage {
        asset {
          gatsbyImageData(
            width: 800
            placeholder: BLURRED
            fit: FILLMAX
          )
        }
      }
    }
  }
`

function BlogPost({data}) {
  return (
    <GatsbyImage 
      image={data.sanityPost.mainImage.asset.gatsbyImageData} 
      alt="Blog post image"
    />
  )
}

The GatsbyImage component automatically:

  • Reserves space using the image's aspect ratio (preventing layout shift)
  • Lazy loads images as they enter the viewport
  • Shows a blurred placeholder while loading
  • Generates responsive srcsets

If You're Using image-url.js Directly

If you need to use @sanity/image-url outside of GraphQL (like in your image-url.js file), you can still prevent jank by:

  1. Query the image dimensions from Sanity and use them to set aspect ratio CSS:
// In your GraphQL query, get dimensions
mainImage {
  asset {
    _id
    metadata {
      dimensions {
        width
        height
        aspectRatio
      }
    }
  }
}
  1. Apply aspect ratio styling to reserve space:
<div style={{
  aspectRatio: `${width} / ${height}`,
  position: 'relative'
}}>
  <img 
    src={imageUrlBuilder.image(imageRef).width(800).url()}
    loading="lazy"
    style={{
      position: 'absolute',
      width: '100%',
      height: '100%',
      objectFit: 'cover'
    }}
  />
</div>

For Portable Text / Block Content

If you're rendering images inside Portable Text, use the @portabletext/react serializer with GatsbyImage:

import {PortableText} from '@portabletext/react'
import {GatsbyImage} from 'gatsby-plugin-image'
import {getGatsbyImageData} from 'gatsby-source-sanity'

const sanityConfig = {projectId: 'your-id', dataset: 'production'}

const components = {
  types: {
    image: ({value}) => {
      const imageData = getGatsbyImageData(
        value.asset._ref,
        {maxWidth: 800},
        sanityConfig
      )
      return <GatsbyImage image={imageData} alt={value.alt || ''} />
    }
  }
}

<PortableText value={portableTextContent} components={components} />

Don't Modify image-url.js - Use gatsbyImageData Instead

The key insight is that you don't need to combine gatsby-image and @sanity/image-url. The gatsby-source-sanity plugin already integrates with gatsby-plugin-image through the gatsbyImageData field, giving you all the performance benefits including preventing layout shift automatically.

Your image-url.js file should only be used for cases where you need direct URL manipulation (like social media meta tags), not for rendering images in your components. For component rendering, always prefer the gatsbyImageData approach which handles aspect ratios, lazy loading, and placeholder generation automatically.

Show original thread
9 replies

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?