How AI is powering better personalization in e-commerce [with Vercel]. Sign up now โ†’

Resolving internal link references in Sanity queries with Astro

11 repliesLast updated: Nov 29, 2025

Hey everyone! ๐Ÿ‘‹
I'm trying to use a Sanity/Astro set up and am having some issues getting 'internal links' to resolve in queries for page block content.
I've tried to use some of the info from several places and feel like I've very close but just can't find the missing piece to make it work for me.

YouTube video some info I thought might help construct the query:
https://www.youtube.com/watch?v=9ipNrJlIj_I I tried to understand some more from here:
https://www.sanity.io/docs/how-queries-work I'm using this plugin for the basic setup:
https://www.sanity.io/plugins/astro-sanity
I'm able to get page content in general outputting perfectly - but for internalLink type blocks in there I'm seeing the references un-resolved. My query is currently set as this:


*[_type == "page" && slug == "what-is-veterinary-physiotherapy"]{
    ...,
    content[]{
        ...,
        markDefs[]{
            ...,
            _type == "internalLink" => {
                ...,
                _type == "reference" => {
                  ...,
                  reference[]->
                }
            }
        }
    }
}
Any ideas where to start/what to change?
๐Ÿ™‚
AI Update

Looking at your query, I can see the issue with how you're trying to resolve internal link references in your Portable Text content. The problem is in the structure of your projection - you have an unnecessary nested check that's preventing proper dereferencing.

Here's the corrected query:

*[_type == "page" && slug == "what-is-veterinary-physiotherapy"]{
    ...,
    content[]{
        ...,
        markDefs[]{
            ...,
            _type == "internalLink" => {
                "slug": @.reference->slug
            }
        }
    }
}

What changed:

How it works:

Important note: If your slug is stored as an object with a current property (which is common in Sanity), you'll need:

*[_type == "page" && slug == "what-is-veterinary-physiotherapy"]{
    ...,
    content[]{
        ...,
        markDefs[]{
            ...,
            _type == "internalLink" => {
                "slug": @.reference->slug.current
            }
        }
    }
}

This pattern is documented in Sanity's guide on joining references in Portable Text. The arrow operator (->) is the key to dereferencing and fetching data from related documents in GROQ queries.

If you need to fetch additional fields from the referenced document (like title, or the entire slug object), you can expand the projection:

markDefs[]{
    ...,
    _type == "internalLink" => {
        "slug": @.reference->slug.current,
        "title": @.reference->title
    }
}
Show original thread
11 replies

Was this answer helpful?

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.

Related contributions