How to create a dynamic homepage reference in Sanity that won't break if slug changes?
You're absolutely right to be concerned about clients changing slugs and breaking your homepage! This is a common problem, and there are several good solutions. Your idea of using a settings page with a reference is actually one of the best approaches.
Recommended Solution: Singleton Settings with Reference
The cleanest way to handle this is to create a singleton settings document that stores a reference to your homepage. Here's how:
1. Create a Settings Schema
First, create a singleton siteSettings document type as described in this guide on creating singleton documents:
// schemas/siteSettings.ts
import {defineField, defineType} from 'sanity'
export default defineType({
name: 'siteSettings',
title: 'Site Settings',
type: 'document',
fields: [
defineField({
name: 'homepage',
title: 'Homepage',
type: 'reference',
to: [{type: 'page'}],
validation: Rule => Rule.required()
}),
// other settings...
]
})2. Set Up as Singleton in Studio
Configure your Structure Builder to make this a singleton:
// structure.ts
export const myStructure = (S) =>
S.list()
.title('Content')
.items([
S.listItem()
.title('Site Settings')
.child(
S.document()
.schemaType('siteSettings')
.documentId('siteSettings')
),
...S.documentTypeListItems().filter(
listItem => !['siteSettings'].includes(listItem.getId())
)
])3. Fetch Homepage in Your Frontend
Then in your Next.js (or other framework) index page:
// app/page.tsx
const query = `*[_id == "siteSettings"][0].homepage->{
title,
content,
// all your page fields
}`
const homepage = await client.fetch(query)Alternative Approaches
Option 2: Document-Level Flag
Add a boolean field isHomepage to your page schema:
defineField({
name: 'isHomepage',
title: 'Set as Homepage',
type: 'boolean',
validation: Rule => Rule.custom((value, context) => {
// You could add validation to ensure only one page is marked as homepage
return true
})
})Then query: *[_type == "page" && isHomepage == true][0]
Option 3: Fixed Document ID
Instead of using slugs, create your homepage with a fixed _id:
// In your initial value template or manually
{
_id: 'homepage',
_type: 'page',
title: 'Home',
// ... other fields
}Then query: *[_id == "homepage"][0]
Why the Settings Reference is Best
The singleton settings with reference approach is the cleanest because:
- ✅ Slug-independent - Clients can change slugs freely
- ✅ User-friendly - Editors can easily change which page is the homepage through the UI
- ✅ Flexible - Easy to add other site-wide settings later
- ✅ Type-safe - References are validated by Sanity
The only downside is it requires an extra query hop, but Sanity's reference resolution makes this very efficient, and you can use reference projections (the -> operator) to resolve it in a single query as shown above.
Show original thread3 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.