How AI is powering better personalization in e-commerce [with Vercel]. Sign up now

Mapping Over Array of Images in Sanity with Next.js urlFor()

3 repliesLast updated: Nov 29, 2025

Mapping Over Array of Image - Hey peeps, I'm using the nextjs starter and I've got a few components I will need to build that must accept multiple image files, for example, grids, image sliders, two column layouts. I'm also trying to adapt the Hero component to accept multiple images that I can cycle through. I've changed the schema to accept an array rather than an object. However I'm having trouble getting this to translate on the front end....


function Hero(props) {
  const { heading, backgroundImage, tagline, ctas, node } = props;

  console.log(backgroundImage);

  return (
    <div className={styles.root}>
      <div className={styles.content}>
        <h1 className={styles.title}>{heading}</h1>
        {backgroundImage.map((background) => (
          <>
            <img src={`${urlFor(backgroundImage).width(2000).auto("format").url()}`} />
          </>
        ))}
        <div className={styles.tagline}>{tagline && <SimpleBlockContent blocks={tagline} />}</div>
        {ctas && (
          <div className={styles.ctas}>
            {ctas.map((cta) => (
              <Cta {...cta} key={cta._key} />
            ))}
          </div>
        )}
      </div>
    </div>
  );
}
AI Update

I can see the issue in your code! You're mapping over backgroundImage array but then still using the entire backgroundImage array inside urlFor() instead of using the individual background item from the map. Here's the fix:

function Hero(props) {
  const { heading, backgroundImage, tagline, ctas, node } = props;

  console.log(backgroundImage);

  return (
    <div className={styles.root}>
      <div className={styles.content}>
        <h1 className={styles.title}>{heading}</h1>
        {backgroundImage.map((background) => (
          <img 
            key={background._key} 
            src={urlFor(background).width(2000).auto("format").url()} 
          />
        ))}
        <div className={styles.tagline}>{tagline && <SimpleBlockContent blocks={tagline} />}</div>
        {ctas && (
          <div className={styles.ctas}>
            {ctas.map((cta) => (
              <Cta {...cta} key={cta._key} />
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

Key changes:

For your schema, make sure it looks something like this:

{
  name: 'backgroundImage',
  title: 'Background Images',
  type: 'array',
  of: [
    {
      type: 'image',
      options: {
        hotspot: true
      }
    }
  ]
}

This pattern will work for all your other components that need multiple images (grids, sliders, two-column layouts). Just remember: when you map over the array, use the iterator variable (like background) inside the map function, not the original array variable.

If you want to add alt text or other metadata to your images, you can enhance the schema with custom fields as described in the Sanity image type documentation:

{
  name: 'backgroundImage',
  title: 'Background Images',
  type: 'array',
  of: [
    {
      type: 'image',
      options: {
        hotspot: true
      },
      fields: [
        {
          name: 'alt',
          title: 'Alt Text',
          type: 'string'
        }
      ]
    }
  ]
}

Then access it in your component: background.alt

Show original thread
3 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