0

I use next/image to load my images in my app. It works fine except for a carousel with multiple images. When I do like this I have that error :

Error: Image is missing required "src" property. Make sure you pass "src" in props to the next/image component. Received: {}

The problem is not because I have an entity without any file

image.js

import { getStrapiMedia } from "../utils/medias"
import NextImage from "next/image"

const Image = (props) => {
  if (!props.media) {
    return <NextImage {...props} />
  }

  const { url, alternativeText } = props.media

  const loader = ({ src }) => {
    return getStrapiMedia(src)
  }

  return (
    <NextImage
      loader={loader}
      layout="responsive"
      objectFit="contain"
      width={props.media.width}
      height={props.media.height}
      src={url}
      alt={alternativeText || ""}
    />
  )
}

export default Image

Carousel.js

import React, { useCallback } from "react"
import useEmblaCarousel from "embla-carousel-react"
import NextImage from "./Image"

export const EmblaCarousel = (product) => {
  const [emblaRef, emblaApi] = useEmblaCarousel()

  useEmblaCarousel.globalOptions = { loop: true }

  const scrollPrev = useCallback(() => {
    if (emblaApi) emblaApi.scrollPrev()
  }, [emblaApi])

  const scrollNext = useCallback(() => {
    if (emblaApi) emblaApi.scrollNext()
  }, [emblaApi])

  return (
    <div className="embla" ref={emblaRef}>
      <div className="embla__container">
        {product.gallery.map((_gallery) => (
          <div key={_gallery.id}>
            <NextImage media={_gallery.image} className="embla__slide" />
          </div>
        ))}
      </div>
      <button
        className="hidden md:inline embla__prev mr-2"
        onClick={scrollPrev}
      >
        Prev
      </button>
      <button
        className="hidden md:inline embla__next ml-2"
        onClick={scrollNext}
      >
        Next
      </button>
    </div>
  )
}

export default EmblaCarousel
Rom-888
  • 681
  • 2
  • 9
  • 30

2 Answers2

2

The issue is

 if (!props.media) {
    return <NextImage {...props} />
  }

in your custom Image component. When the media prop is falsy like undefined or null, you're passing everything else to NextImage but that everything else doesn’t include src prop which is mandatory for next Image component. Also your url extraction is dependent on media prop to be truthy and have a property called url. Can be seen from the next line :-

const { url, alternativeText } = props.media

And you intend to pass this url to src as can be seen from your usage. Either you can return null when media is falsy or you can filter out those items in your list where media prop is falsy and then map on it.

Lakshya Thakur
  • 8,030
  • 1
  • 12
  • 39
  • I see yes. But, if I return null, I don't have the error anymore, but I still don't have the pictures – Rom-888 Mar 26 '22 at 15:11
  • It should have the media prop actually. I don't understand why It doesn't get it – Rom-888 Mar 26 '22 at 15:18
  • I tried to use directly the next/image without the image.js component, but it still doesn't give me anything. It got the image url because I needed to add the domain in next.config – Rom-888 Mar 26 '22 at 16:53
0

Not sure if you ever found an answer for this but I was running into the same issue and noticed that when looping through the multiple images object from Strapi the object is slightly different than with single images.

To fix this issue I supplied it to the getStrapiMedia() function in the same way it expects single images i.e:

{aboutpage?.attributes.shareCta.images.data.slice(0, 4).map((image) => (
<div key={image.id} className="relative h-64 w-full">
  <Image
    layout="fill"
    objectFit="cover"
    placeholder="blur"
    blurDataURL={blurDataUrl}
    src={
      getStrapiMedia({ data: image }) ||
      "/images/placeholders/image-placeholder.png"
    }
  />
</div>
  ));
}

Hope this helps and kind regards

Brams
  • 1
  • 1