Gabriel Pedroza
Gabriel Pedroza

Reputation: 64

Sanity.io and Image from next/image issue

This is my first official post on Stack so bear with me; I am currently using Nextjs with Sanity as my headless CMS and I'm encountering what seems to be a TypeScript type issue. GH: https://github.com/GabrielPedroza/e-commerce/blob/main/components/Product.tsx

<Image src={urlFor(image && image[0]!)} />

import imageUrlBuilder from "@sanity/image-url"
import { SanityImageSource } from "@sanity/image-url/lib/types/types"

export const client = sanityClient({
    projectId: "gz95qrem",
    dataset: "production",
    apiVersion: "2022-04-27",
    useCdn: true,
    token: process.env.NEXT_PUBLIC_SANITY_TOKEN, // for security purposes
})

const builder = imageUrlBuilder(client)

export const urlFor = (source: SanityImageSource) => {
    return builder.image(source)
} 
Type 'ImageUrlBuilder' is not assignable to type 'string | StaticImport'.
  Property 'src' is missing in type 'ImageUrlBuilder' but required in type 'StaticImageData'.ts(2322)
image.d.ts(19, 5): 'src' is declared here.
image.d.ts(29, 5): The expected type comes from property 'src' which is declared here on type 'IntrinsicAttributes & Omit<DetailedHTMLProps<ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, "ref" | ... 4 more ... | "loading"> & { ...; }'

Server Error
Error: Image is missing required "src" property. Make sure you pass "src" in props to the `next/image` component. Received: {}
Call Stack
Image
node_modules/next/dist/client/image.js (160:18)
renderWithHooks
file:///Users/gabrielpedroza/Code/e-commerce/node_modules/react-dom/cjs/react-dom-server.browser.development.js (5448:16)
renderIndeterminateComponent
file:///Users/gabrielpedroza/Code/e-commerce/node_modules/react-dom/cjs/react-dom-server.browser.development.js (5521:15)
renderElement
file:///Users/gabrielpedroza/Code/e-commerce/node_modules/react-dom/cjs/react-dom-server.browser.development.js (5736:7)
renderNodeDestructive
file:///Users/gabrielpedroza/Code/e-commerce/node_modules/react-dom/cjs/react-dom-server.browser.development.js (5875:11)
renderNode
file:///Users/gabrielpedroza/Code/e-commerce/node_modules/react-dom/cjs/react-dom-server.browser.development.js (6009:12)
renderHostElement
file:///Users/gabrielpedroza/Code/e-commerce/node_modules/react-dom/cjs/react-dom-server.browser.development.js (5433:3)
renderElement
file:///Users/gabrielpedroza/Code/e-commerce/node_modules/react-dom/cjs/react-dom-server.browser.development.js (5742:5)
renderNodeDestructive
file:///Users/gabrielpedroza/Code/e-commerce/node_modules/react-dom/cjs/react-dom-server.browser.development.js (5875:11)
renderNode
file:///Users/gabrielpedroza/Code/e-commerce/node_modules/react-dom/cjs/react-dom-server.browser.development.js (6009:12)

One way to remove the error is to just use a string or use ts-ignore but this obviously can't be used in my scenario since I'm using Sanity. My temporary dirty solution is to use the regular img tag and use a ts-ignore so it would work. I tried asking at the official Next discord server, overall googling and reading docs but can't really find a solution to this.

Upvotes: 4

Views: 7499

Answers (3)

kriscondev
kriscondev

Reputation: 875

I'm using Next13 and sanity.io(this is where I'll pull the images) and deploying my app to Vercel. Thanks to @javiRelax for the hint. This how it works for me:

     {Images.map((array, index) => {         
        return(           
          <Image
          src={urlFor(array.imgUrl).url()}
          alt={array.alt}
          key={index}
          width="100"
          height="100"
          unoptimized={true} 
          />
        );
      })}
              

I added the

unoptimized={true}

for some reason it doesn't work without it.

Upvotes: 0

JaviRelax
JaviRelax

Reputation: 11

i was having the same issue..

my solution was doing this before the call in the src Image:

src={urlFor(image).url()};

and in my files where i define the types of my schema, i also change the type of "image" for "SanityImageSource"

Greetings!

Upvotes: 1

Gabriel Pedroza
Gabriel Pedroza

Reputation: 64

Figured out a clean solution:

const src = urlFor(image && image[0]).url()

<Image loader={() => src} src={src} layout='fill' />

``` Wrap the Image component in a div tag and make sure it is `position: relative;` so layout='fill' would work properly if you want to make your images responsive

Upvotes: 0

Related Questions