How to model a hierarchical tree-structure taxonomy in Sanity?
Great question! For modeling Norwegian counties and municipalities with flexible selection options, you'll want to use reference fields with parent-child relationships. Here's how to set this up:
Basic Schema Structure
Create a location document type where each location can optionally reference a parent:
// schemas/location.js
import {defineField, defineType} from 'sanity'
export default defineType({
name: 'location',
title: 'Location',
type: 'document',
fields: [
defineField({
name: 'title',
type: 'string',
title: 'Name'
}),
defineField({
name: 'parent',
type: 'reference',
to: [{type: 'location'}],
// This ensures we can only select parent locations (not children)
options: {
filter: '!defined(parent)',
},
}),
],
})This gives you:
- Country level: Documents with no parent (Norway)
- County level: Documents with country as parent (Viken)
- Municipality level: Documents with county as parent (Fredrikstad)
How to Use in Other Documents
When you want users to select locations (say, in a post or event document), you can allow them to select any level of the hierarchy:
defineField({
name: 'locations',
type: 'array',
of: [{
type: 'reference',
to: [{type: 'location'}]
}]
})Or restrict to only specific levels (like only municipalities):
defineField({
name: 'municipality',
type: 'reference',
to: [{type: 'location'}],
options: {
filter: 'defined(parent)' // Only show locations that have a parent
}
})Querying the Hierarchy
When querying, you can "follow" the references up the tree:
*[_type == "post"]{
title,
locations[]->{
title,
parent->{
title,
parent->
}
}
}Studio Setup with Structure Builder
For a better editing experience, check out the Creating a Parent/Child Taxonomy guide. It shows how to:
- Set up filtered document lists for each parent
- Use initial value templates to pre-fill the parent field
- Create a nice hierarchical view in the Studio
The key insight: references in Sanity are bidirectional when queried, but only appear in the UI where they're defined. So even though you put the parent field on the child document, you can query in both directions!
Show original thread8 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.