Next.js Image component with Sanity.io: src error despite adding source

6 replies
Last updated: Feb 27, 2022
Hi,I used 
Sanity.io  Headless CMS to set up a blog on my Next.js project but I got a warning that I shouldn't use img tag and instead use the Image component.I tried using Image but got an error that there is no src but I added the src, I think the Image and img are used differently.
Does someone have experience working with 
Sanity.io  and Next/Image? I have installed the sanity Client and next-sanity-image libraries. I also updated next/config with
module.exports = {
reactStrictMode: true,
images: {
domains: ["<http://cdn.sanity.io|cdn.sanity.io>"],
AI Update

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 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-url

2. 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 thread
6 replies
Hey Vincent! It's hard to say without seeing the error, but I'd say it's likely because you're not passing an image asset to your imageUrlBuilder. An image field in the schema is a reference to an asset, so you need to expand it in your query as outlined here . Something like this should get it for you:
'*[ _type == "post" ]{
  ...,
  mainImage->
}'
I'd also suggest using the
next-sanity package in your project. It'll help streamline your queries and provide some handy Next-specific tools.
Hi
user M
the error I Got in the next.js app is:
Error: Image is missing required "src" property. Make sure you pass "src" in props to the `next/image` component. Received: {"width":500,"height":500}
I should have elaborated. If I comment out lines 52 to 56 and uncommented lines 57 to 63, that's the error I got.

When you said "because you're not passing an image asset to your imageUrlBuilder. An image field in the schema is a reference to an asset" do you mean I'm not passing the right parameter to the ImageUrlBuilder? Should I pass p.image.source.asset.ref to imageUrlBuilder instead?
user B

Here is how I have solved this in Nextjs:


const urlFor = (source: SanityImageSource) => createImageUrlBuilder(config).image(source);

/* projects is prop sent in from projects page */

 {projects.map(
        ({ projectimage }) => (

{projectimage && (
                    <Image
                      height="255"
                      width="500"
                      src={urlFor(projectimage).url() as string}
                      alt={name}
                      role="presentation"
                    />
                  )}
}
user B

Here is how I have solved this in Nextjs:


```
const urlFor = (source: SanityImageSource) => createImageUrlBuilder(config).image(source);

/* projects is prop sent in from projects page */

 {projects.map(
        ({ projectimage }) => (

{projectimage && (
                    <Image
                      height="255"
                      width="500"
                      src={urlFor(projectimage).url() as string}
                      alt={name}
                      role="presentation"
                    />
                  )}
}
```
Use this package instead to avoid these hassles. https://www.npmjs.com/package/next-sanity-image
thanks for the tips guys. I finally got it!

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?