
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeYou'll need to create a custom input component to achieve dynamic options from Sanity. Unfortunately, you can't use async functions or queries directly in the options.list field of a schema definition - it only accepts static arrays.
Here's how to solve this with a custom input component:
First, create a custom input component that fetches pages dynamically using the useClient hook:
// components/PageSelectInput.tsx
import { useClient } from 'sanity'
import { StringInputProps, set, unset } from 'sanity'
import { useEffect, useState } from 'react'
import { Stack, Select } from '@sanity/ui'
export function PageSelectInput(props: StringInputProps) {
const { value, onChange } = props
const client = useClient({ apiVersion: '2024-01-01' })
const [pages, setPages] = useState<Array<{ _id: string; title: string }>>([])
const [loading, setLoading] = useState(true)
useEffect(() => {
// Fetch all pages from Sanity
client
.fetch(`*[_type == "page"]{ _id, title, "slug": slug.current }`)
.then((result) => {
setPages(result)
setLoading(false)
})
.catch((error) => {
console.error('Error fetching pages:', error)
setLoading(false)
})
}, [client])
const handleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
const newValue = event.target.value
onChange(newValue ? set(newValue) : unset())
}
return (
<Stack space={3}>
<Select
value={value || ''}
onChange={handleChange}
disabled={loading}
>
<option value="">Select a page</option>
{pages.map((page) => (
<option key={page._id} value={page._id}>
{page.title}
</option>
))}
</Select>
</Stack>
)
}Then reference this custom component in your schema:
import { PageSelectInput } from './components/PageSelectInput'
{
name: 'goToPage',
title: 'Go to page',
description: 'This will be the page you would like the users to go to.',
type: 'string',
components: {
input: PageSelectInput
}
}If you're storing page IDs anyway, consider using Sanity's built-in reference field instead:
{
name: 'goToPage',
title: 'Go to page',
type: 'reference',
to: [{ type: 'page' }],
options: {
filter: '_type == "page"' // Optional: add custom filters
}
}This gives you a searchable dropdown with all pages automatically, without needing a custom component. The reference field also ensures data integrity and lets you easily resolve the full page document when querying.
The custom input approach gives you more control over the UI and what values are stored (like storing slugs instead of IDs), while the reference approach is simpler and more maintainable for typical use cases where you're linking to other documents.
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.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store