How to resolve references in resolveProductionUrl for preview iframe?
The document passed to resolveProductionUrl doesn't include resolved references by default - you're absolutely right. You need to fetch the full document data yourself using Sanity's client within the resolveProductionUrl function.
The key is making resolveProductionUrl an async function and using a GROQ query with the reference operator (->) to dereference the category:
import { client } from './sanityClient' // Your configured client
export const resolveProductionUrl = async (doc) => {
if (doc._type !== 'article') return undefined
// Fetch the document with the resolved category reference
const article = await client.fetch(
`*[_id == $id][0]{
"categorySlug": category->slug.current,
"articleSlug": slug.current
}`,
{ id: doc._id }
)
if (!article?.categorySlug || !article?.articleSlug) return undefined
const baseUrl = 'https://your-site.com' // or process.env.NEXT_PUBLIC_SITE_URL
return `${baseUrl}/${article.categorySlug}/${article.articleSlug}`
}The category-> syntax in the GROQ query tells Sanity to resolve the reference and fetch the actual category document. Then category->slug.current gets the slug from that resolved document.
A few things to note:
- Make it async: The function needs to be async since you're fetching data
- Use the document's
_id: Thedocparameter has the_id, which is stable and works even for drafts - Handle missing data: Always check that both slugs exist before constructing the URL
- Consider drafts: If you want preview URLs for draft documents, you might need to query
*[_id in [$id, "drafts." + $id]]to handle both published and draft versions
If you're using the sanity-plugin-iframe-pane, the same approach works - just pass your async resolveProductionUrl function to the plugin's url option.
Show original thread11 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.