
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeI understand your frustration! Unfortunately, the prepare function has a significant limitation in Sanity v3: it cannot make custom GROQ queries or access the Sanity client. This is explicitly documented as a limitation of the preview system.
The prepare function only receives the selection object you define in select, and there's no second context parameter with client access. This is by design - the select syntax handles dereferencing, but only in specific, predefined ways.
Since you need to query data (like following references in the opposite direction), here are the viable approaches:
Instead of relying on prepare, you can create a custom preview component using the Form Components API. This is a React component where you can use the useClient hook:
import {useClient} from 'sanity'
import {defineType} from 'sanity'
import React from 'react'
const CustomPreview = (props: any) => {
const client = useClient({apiVersion: '2024-01-01'})
const [parentTitle, setParentTitle] = React.useState('')
React.useEffect(() => {
client.fetch('*[references($id)][0]{title}', {id: props.id})
.then(result => setParentTitle(result?.title || ''))
.catch(() => setParentTitle(''))
}, [props.id, client])
return props.renderDefault({
...props,
title: parentTitle ? `${parentTitle} - ${props.title}` : props.title
})
}
export default defineType({
name: 'myDocument',
type: 'document',
components: {
preview: CustomPreview
},
preview: {
select: {
title: 'title',
id: '_id'
}
}
})This approach gives you full React component capabilities, including hooks like useClient, and you can use the renderDefault function to wrap the existing preview behavior while enhancing it with your custom data.
select with Direct ReferencesIf you're following a forward reference (not reverse), you can use dot notation in select to access referenced document fields:
preview: {
select: {
title: 'title',
parentTitle: 'parent.title' // Works for forward references
},
prepare({title, parentTitle}) {
return {
title: parentTitle ? `${parentTitle} - ${title}` : title
}
}
}But this only works for references defined on the document, not reverse lookups like your use case requires.
If the relationship is important for previews, consider storing the data you need directly on the document rather than requiring a reverse reference lookup. This isn't always practical, but it's the most performant option since it avoids additional queries.
In v3, Sanity moved away from the parts system to a more explicit architecture. The prepare function is intentionally kept as a pure transformation function without side effects or async operations. For scenarios requiring data fetching, custom preview components with hooks are the recommended pattern - they're more powerful and align with modern React practices.
The trade-off is that custom components require more code, but they give you full control over the rendering and data fetching logic. The Form Components API provides this flexibility while maintaining type safety and integration with Studio's real-time collaboration features.
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.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store