Accessing nested product titles in Sanity collection array

12 replies
Last updated: Nov 29, 2025
Hi all,I'm having trouble targeting the second array layer : This is what I have at the moment

const Home = ({ product, collection }) => {
  return (
    <>
      <Collection collection={collection} />
      {(collection ?? []).map((collection) => (
        <div key={collection.title}>
          {console.log(collection.products)}</div>
      ))}
    </>
  );
};
Now I can do

{console.log(collection.products)}
this shows me the products inside the collection but my goal is to fetch the title of the products in the collection so one would say it should be like this

{console.log(collection.products.title)}
but this wont work as it returns undefined. I have a feeling there needs a second mapping for this?

This is the data I want to target
AI Update

This is a classic nested array issue! You're absolutely right that you need a second mapping. The problem is that collection.products is an array, so you can't access .title directly on it - you need to map through that array as well.

Here's how to fix it:

const Home = ({ product, collection }) => {
  return (
    <>
      <Collection collection={collection} />
      {(collection ?? []).map((collection) => (
        <div key={collection.title}>
          {/* Map through the products array */}
          {(collection.products ?? []).map((product) => (
            <div key={product._id || product.title}>
              {product.title}
            </div>
          ))}
        </div>
      ))}
    </>
  );
};

What's happening:

  1. Your first map iterates through the collection array
  2. Inside each collection, collection.products is another array of product objects
  3. You need a second .map() to iterate through each product in that array
  4. Then you can access product.title on each individual product object

A few tips:

  • I added the ?? [] safety check on collection.products too, in case a collection has no products
  • Use a unique key like product._id if available (Sanity documents have _id fields), falling back to product.title if needed
  • If you're just debugging, you could also do {console.log(collection.products[0]?.title)} to see the first product's title

If you're still getting undefined:

Make sure your GROQ query is actually fetching the product data. If products is a reference field, you need to dereference it in your query:

*[_type == "collection"] {
  title,
  products[]-> {
    title,
    _id
  }
}

The -> operator dereferences the product references so you get the actual product data, not just the reference IDs. Check out the GROQ references documentation for more details on how dereferencing works in Sanity queries.

Show original thread
12 replies

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.

Was this answer helpful?