Poor image quality when displaying Sanity images in Next.js Image component
This is a common issue! The problem is likely that you're not properly utilizing Sanity's image URL builder to construct optimized image URLs with the right dimensions and quality settings. When you just use the raw image reference from Sanity with Next.js Image, you're probably not getting the full-resolution or properly-sized version.
Here's what you need to do:
Install the @sanity/image-url package:
npm install @sanity/image-url
# or
pnpm add @sanity/image-urlCreate a URL builder helper function:
Create a utility file (e.g., lib/imageUrl.ts) with this code:
import imageUrlBuilder from '@sanity/image-url'
import { client } from './sanity' // your Sanity client
const builder = imageUrlBuilder(client)
export function urlFor(source) {
return builder.image(source)
}Configure Next.js to allow Sanity's CDN:
In your next.config.js (or next.config.ts):
const nextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'cdn.sanity.io',
},
],
},
}
module.exports = nextConfigUse the URL builder with next/image:
Now when displaying your product images:
import Image from 'next/image'
import { urlFor } from '@/lib/imageUrl'
export function ProductImage({ image }) {
return (
<Image
src={urlFor(image).width(800).quality(90).url()}
alt={image.alt || 'Product image'}
width={800}
height={600}
sizes="(max-width: 768px) 100vw, 800px"
/>
)
}The key things here:
.width(800)- Request the appropriate size (adjust to your needs).quality(90)- Set quality level (default is 75, but 90 gives better quality).auto('format')- Optional but recommended - automatically serves WebP/AVIF to supported browsers.url()- Converts to the actual URL string
You can also add .auto('format') for automatic format optimization:
src={urlFor(image).width(800).quality(90).auto('format').url()}This leverages Sanity's powerful image CDN which provides on-demand image transformations with automatic caching. The @sanity/image-url package makes it easy to construct these optimized URLs programmatically.
Bonus tip: You can also use Sanity's built-in LQIP (Low Quality Image Placeholder) data with Next.js's blur placeholder feature for a nice progressive loading effect:
<Image
src={urlFor(image).width(800).quality(90).url()}
placeholder="blur"
blurDataURL={image.asset.metadata.lqip}
alt="Product"
width={800}
height={600}
/>If you're still seeing quality issues after this, try increasing the width parameter and quality setting to match your actual display size!
Show original thread5 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.