How to get parent document slugs in nested Sanity structure?

6 replies
Last updated: Nov 29, 2025
Is there a method in the Studio to get the slugs from all parent documents?
I have a nested structure of
/:module/:chapter/:section
and I’d like to get the chapter and module slugs when fetching the section
AI Update

Based on what you're describing, you have a hierarchical structure where sections reference chapters, and chapters reference modules. There isn't a built-in "get all parent documents" method in Sanity Studio, but you can absolutely achieve this using GROQ queries with reference dereferencing.

Schema Setup

First, make sure your schema uses reference fields to establish the parent relationships:

// section.js
{
  name: 'section',
  type: 'document',
  fields: [
    {
      name: 'slug',
      type: 'slug'
    },
    {
      name: 'chapter',
      type: 'reference',
      to: [{type: 'chapter'}]
    }
  ]
}

// chapter.js
{
  name: 'chapter',
  type: 'document',
  fields: [
    {
      name: 'slug',
      type: 'slug'
    },
    {
      name: 'module',
      type: 'reference',
      to: [{type: 'module'}]
    }
  ]
}

Fetching Parent Slugs

When querying for a section, you can use GROQ's -> operator to follow references and get the parent slugs:

*[_type == "section" && slug.current == $sectionSlug][0] {
  slug,
  "chapterSlug": chapter->slug.current,
  "moduleSlug": chapter->module->slug.current
}

This query:

  • Finds your section by its slug
  • Follows the chapter reference with -> to get the chapter's slug
  • Chains another -> to follow the chapter's module reference

You can also get the full parent objects if you need more than just slugs:

*[_type == "section" && slug.current == $sectionSlug][0] {
  slug,
  chapter-> {
    slug,
    module-> {
      slug
    }
  }
}

In Studio Context

If you need to access this information within the Studio (for example, in a custom component or plugin), you can use the Sanity client to run these queries:

import {useClient} from 'sanity'

const client = useClient({apiVersion: '2024-01-01'})

const result = await client.fetch(
  `*[_type == "section" && _id == $id][0] {
    slug,
    "chapterSlug": chapter->slug.current,
    "moduleSlug": chapter->module->slug.current
  }`,
  {id: documentId}
)

The key insight from the reference fields documentation is that references in Sanity are bidirectional when queried, meaning you can traverse them efficiently in either direction using GROQ's dereferencing operator (->).

This approach gives you full control over which parent information you need and avoids storing redundant slug data in your documents, keeping your content normalized and easier to maintain.

Show original thread
6 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.

Was this answer helpful?