Handling nested references in Sanity preview function
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.hexorcards[]->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] }),
};
},
}Option 2: Resolve References Manually (Recommended for Dynamic Arrays)
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! 🚀
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.