Next.js Image component with Sanity.io: src error despite adding source
I can help you use Sanity images with Next.js Image component! The issue you're experiencing is that Sanity image objects aren't simple URL strings - they're structured objects that need to be converted into URLs first.
The Recommended Approach: @sanity/image-url
The official way to use Sanity images with Next.js is with the @sanity/image-url package. This helper library converts Sanity image objects into proper URLs that Next.js Image component can use.
1. Install the package:
npm install @sanity/image-url2. Create a helper function:
// lib/imageUrl.ts
import imageUrlBuilder from '@sanity/image-url'
import { client } from './sanity.client' // your sanity client
const builder = imageUrlBuilder(client)
export function urlFor(source) {
return builder.image(source)
}3. Update your Next.js config:
Your config needs a small fix - use remotePatterns (the modern approach) instead of domains, and make sure you're using https:
module.exports = {
reactStrictMode: true,
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'cdn.sanity.io',
},
],
},
}4. Use it with Next.js Image component:
import Image from 'next/image'
import { urlFor } from '@/lib/imageUrl'
export default function BlogPost({ post }) {
return (
<Image
src={urlFor(post.mainImage).width(800).url()}
alt={post.mainImage.alt || ''}
width={800}
height={600}
/>
)
}Why This Works
Sanity stores images as objects with a structure like:
{
"_type": "image",
"asset": {
"_ref": "image-abc123...",
"_type": "reference"
}
}You can't pass this object directly to src - you need to convert it to an actual URL. That's what urlFor() does. It takes the Sanity image object and builds a proper CDN URL like https://cdn.sanity.io/images/[project-id]/[dataset]/[asset-id]-[dimensions].jpg.
Powerful Image Transformations
The @sanity/image-url package also gives you on-demand image transformations through Sanity's Image Pipeline:
.width(800)- set width.height(600)- set height.quality(90)- adjust quality.format('webp')- change format.auto('format')- automatically serve WebP/AVIF to supporting browsers.fit('crop')- control how images are resized
Example with transformations:
<Image
src={urlFor(post.mainImage)
.width(800)
.height(600)
.auto('format')
.quality(90)
.url()}
alt={post.mainImage.alt || ''}
width={800}
height={600}
/>About next-sanity-image
You mentioned you installed next-sanity-image - this is a community library that provides an alternative approach with a useNextSanityImage hook. Both approaches work fine! The @sanity/image-url approach shown above is the official Sanity package and works well with both Next.js Pages Router and App Router. It's simpler since it doesn't require hooks, which makes it particularly convenient for Server Components in the App Router.
The key takeaway: always convert Sanity image objects to URLs using @sanity/image-url (or your chosen helper library) before passing them to Next.js Image component!
Show original thread6 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.