Discussion on using next-optimized-images with Sanity's CDN and potential issues with next/image and lazy loading.

36 replies
Last updated: Feb 23, 2021
Hi chat. I'm reading through next-optimized-images with the intention of paring it with Sanity's CDN. My understanding is that next-optimized-images only loads images from the filesystem. Is this correct or am I missing something and I can load remote images?
You can now import or require your images directly in your react components:
export default () => (
  <div>
    <img src={require('./images/my-image.jpg')} />
    <img src={require('./images/my-small-image.png')} />
    <img src={require('./images/my-icon.svg')} />
  </div>
);
AI Update

You're correct that next-optimized-images primarily works with images from the filesystem through webpack imports. However, for working with Sanity's CDN, you don't actually need next-optimized-images at all - Sanity provides its own powerful image optimization solution that's better suited for remote images.

Sanity's Image Pipeline is an on-demand image transformation service that handles all the optimization you'd want from next-optimized-images (and more) directly through URL parameters. When you upload images to Sanity's Content Lake, they're automatically available through the global CDN at cdn.sanity.io with support for:

  • Automatic format conversion (WebP, AVIF) with auto=format
  • Dynamic resizing and cropping
  • Quality optimization
  • Hotspot/focal point preservation
  • Global CDN caching

For Next.js specifically, the recommended approach is to use Sanity's image URLs with Next.js's built-in <Image> component. You can use the @sanity/image-url helper library to build optimized URLs programmatically:

import imageUrlBuilder from '@sanity/image-url'
import Image from 'next/image'

const builder = imageUrlBuilder(client)

function urlFor(source) {
  return builder.image(source)
}

export default function MyComponent({ image }) {
  return (
    <Image
      src={urlFor(image).width(800).url()}
      alt={image.alt}
      width={800}
      height={600}
    />
  )
}

There's also a community package called next-sanity-image that provides even tighter integration between Sanity's Image Pipeline and Next.js's Image component, handling the props mapping automatically.

So to directly answer your question: yes, next-optimized-images is designed for filesystem imports, but you don't need it for Sanity images - Sanity's CDN already provides all the optimization features you need for remote images.

I think next-optimised-images only loads local images, yes! next/image might suit for your use-case?
If you want a drop in solution you might want to check https://github.com/bundlesandbatches/next-sanity-image
user S
That was my understanding. Next/image only works with select image optimiser platforms which I'm not intending on using
user L
Thanks Raffi, I tested next-sanity-image last week but found it didn't suffice and unfortunately didn't commit a git log as to why.
What was wrong?
To be honest, I can't remember.
Thought i’d ask incase we had the same issues, but thanks anyway.
I think it was related to the layout I was trying to achieve. Using tailwind and an image grid I needed the images to present full width by 'x' height. The plugin/module wraps the image in a div and I think I couldn't get the image to reliably to respond, resize and crop the height correctly when two images were placed side by side with different heights in a css grid.
ok. I think you were getting caught by the next/image layout wrappers.
it adds a number of wrappers to deal with responsiveness as default
Whereas you might want to build the srcset for the image tag yourself.
This is the layout solution which has been achieved simply by using sanity's imageUrlBuilder. All of these images vary in height but I'm able to crop them using my own component with srcset.
Nice grid.
Next/image does but the issue with next wasn't the wrappers the dependancy on vercel and image processing platforms was the blocker.
nextimage can be passed a builder and whitelist on asset domains https://nextjs.org/docs/api-reference/next/image#loader
That’s what it preconfigures under the hood for the default platforms.
Hmm,
I'll take a look. I had researched things quite a bit but perhaps I overlooked this.
Sometimes it’s nice to roll your own, so you bypass the magic too.
Yeah, I'm happy with the component I've made and Sanity's urlBuilder but I'm after lazy loading too.
I thought nextjs did a simple
loading="lazy"
attribute
Proper lazy loading relies on something like intersection observer
and also for safari support
Next/image does, hence I'll take a look at you loading reference.
I'm using react-intersection-observer for scrolling animations so perhaps I can leverage that but I haven't looked into it.
Yeah we’ve done that before with vanilla-lazyload https://github.com/verlok/vanilla-lazyload#usage-with-react
Thanks
user L
I'll dive into both your references
What issue are you having?
Thanks for the pointer.
We didn’t really have an issue as such, was just around image sizing when we were setting things up.
and the default image size being too large.
Ah k.
Well thanks agian
again*
Just for reference if this comes up in a search. I experimented with next/image and was reminded that next/image requires a width and height to be set. This wasn't workable in my use case as image heights vary and need to be unspecified. I ended up using react-intersection-observer to lazy load image which was straight forward https://github.com/thebuilder/react-intersection-observer/blob/HEAD/docs/Recipes.md#lazy-image-load

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?