Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

162
Views
Next/image doesn't load my src image when I use a map

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
about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

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.

about 4 years ago · Juan Pablo Isaza Report

0

Replace NextImage with Image

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

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

  const { url, alternativeText } = props.media

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

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

export default NextImage

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
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!