Selecting nested theme values from array of referenced objects in preview

6 replies
Last updated: Jan 27, 2026
Hey everyone! 👋
I’m trying to get a nested array of referenced objects inside the preview function, but I’m running into some issues. My schema looks something like this:


preview: {
  select: {
    cards: 'cards',
    theme: 'cards[].theme.hex',
  },
  prepare({ cards, theme }) {
    return {
      title: 'Dual',
      subtitle: 'Dual Block',
      media: withCustomParams(DualMedia, { cards }),
    };
  },
},
The cards array contains references to another document type, and each referenced document has a theme.hex field. However, I’m not sure how to correctly select the nested theme values from these referenced objects.

I’ve checked the
Sanity docs on previews , but it only covers direct references, not arrays of references.
Is there a recommended way to handle this in select? Or do I need to resolve the references manually in prepare?

Thanks in advance!
🚀
AI Update

Unfortunately, the preview.select syntax in Sanity doesn't support dereferencing arrays of references directly. The syntax cards[].theme.hex won't work because the preview system can't automatically resolve multiple references in an array.

Here's what you need to know based on the preview configuration documentation:

What works:

  • Single references: author.name (dereferences one document)
  • Array indices: cards.0.theme.hex (gets the first item)

What doesn't work:

  • Array dereferencing: cards[].theme.hex or cards[]->theme.hex

Solutions

Option 1: Access Individual Array Items

If you only need a few items from the array, you can select them by index:

preview: {
  select: {
    cards: 'cards',
    theme0: 'cards.0.theme.hex',
    theme1: 'cards.1.theme.hex',
  },
  prepare({ cards, theme0, theme1 }) {
    return {
      title: 'Dual',
      subtitle: 'Dual Block',
      media: withCustomParams(DualMedia, { cards, themes: [theme0, theme1] }),
    };
  },
}

Since the prepare function receives the raw data including reference IDs, you'll need to handle the full resolution in your custom preview component. Pass the cards array as-is and fetch the referenced data in your DualMedia component using a GROQ query:

preview: {
  select: {
    cards: 'cards',
  },
  prepare({ cards }) {
    return {
      title: 'Dual',
      subtitle: 'Dual Block',
      media: withCustomParams(DualMedia, { cards }),
    };
  },
}

Then in your DualMedia component, use the Sanity client to fetch the full referenced documents with their theme data:

import { useEffect, useState } from 'react';
import { client } from './sanityClient';

function DualMedia({ cards }) {
  const [resolvedCards, setResolvedCards] = useState([]);
  
  useEffect(() => {
    if (!cards?.length) return;
    
    const cardIds = cards.map(card => card._ref);
    client.fetch(
      `*[_id in $ids]{ ..., theme-> }`,
      { ids: cardIds }
    ).then(setResolvedCards);
  }, [cards]);
  
  // Render using resolvedCards with theme.hex available
}

This is a known limitation mentioned in the Sanity community discussions, where complex nested references require manual resolution rather than relying on the select syntax.

The preview system is intentionally limited to prevent performance issues from deeply nested queries running every time a document list renders. For arrays of references, manual resolution gives you more control over when and how the data is fetched.

Hope this helps! 🚀

Show original thread
6 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?