Portable Text link reference not resolving in GROQ query with markDefs
I can see you're dealing with two issues here: the GROQ query not properly dereferencing links in markDefs, and a UI issue with double-clicking in Studio. Let me help you troubleshoot both.
The GROQ Query Issue
Looking at your query output, the markDefs array in your body is not being expanded properly - it's showing the reference object {"_ref": "...", "_type": "reference"} instead of the resolved slug. The issue is that markDefs lives inside each block within the body array, not at the top level of your query.
Your current query structure has the markDefs expansion outside and separate from the body[] projection. You need to move it inside the body projection. Based on this community answer about resolving references in Portable Text, you need to use the @ operator to reference the current scope when dealing with references inside arrays.
Try this corrected structure:
*[_type == "post"][7] {
title,
slug { current },
publishedAt,
"author": author->name,
mainImage,
"categories": categories[]->title,
"website": website->webName,
body[]{
...,
asset->{
...,
"_key": _id
},
_type == "productTable" => {
"productImg1": @.productImage1.asset->url,
"productImg2": @.productImage2.asset->url,
"productImg3": @.productImage3.asset->url,
"productImg4": @.productImage4.asset->url,
},
markDefs[]{
...,
_type == "refLink" => {
"slug": @.reference->slug
},
_type == "extLink" => {
"href": @.href
}
}
}
}The key changes:
- Move
markDefs[]inside thebody[]{}projection - Use
@.reference->slugto dereference the internal link (the@operator refers to the current markDef object) - For external links, you probably just want
@.hrefsince they typically don't have references
According to the Portable Text annotations documentation, each block has its own markDefs array, so you need to expand it at the block level.
The Double-Click Studio Issue
The "Invalid block value" error and needing to click twice to open link options sounds like a schema configuration issue. A few things to check:
- Make sure your annotation types are defined as separate object types at the schema root level (not just inline in your block content definition)
- Verify they're correctly referenced in your block content's
marks.annotationsarray - Check for duplicate definitions - the double-click behavior often happens when there's a schema mismatch
Your refLink and extLink should each be defined something like:
defineType({
name: 'refLink',
type: 'object',
title: 'Internal Link',
fields: [
{
name: 'reference',
type: 'reference',
to: [{type: 'post'}] // or whatever document types you're linking to
}
]
})Then in your block content schema:
marks: {
annotations: [
{name: 'refLink', type: 'refLink'},
{name: 'extLink', type: 'extLink'}
]
}The "Invalid block value" message typically means the data structure being created doesn't match what your schema expects. Check your browser console for any schema validation warnings when you're editing - they'll give you more specific clues about what's mismatched.
If you're still seeing issues after these changes, share your schema definitions for refLink and extLink and I can help spot any configuration problems!
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.