Sanity Pioneers: Get early access to betas, extra AI credits, and a direct line to the engineering team. Apply now

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

6 repliesLast updated: Dec 1, 2025

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:

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

Was this answer helpful?

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.

Related contributions