import {PortableText, type InferComponents, defineQuery} from 'next-sanity'
import {sanityFetch} from '@/sanity/lib/live'
export default async function Page({slug}: {slug: string}) {
const query = defineQuery(`*[_type == "post" && slug.current == $slug][0]{title,content}`)
const {data} = await sanityFetch({query, params: {slug}})
const components = {
block: {
// custom types are autocompleted and fully typed
},
} satisfies InferComponents<typeof data.content>
return (
<>
...
{Array.isArray(data?.content) && <PortableText components={components} value={data.content} />}
</>
)
}
Infer Portable Text components from a value type. This matches the inference behavior of the
componentsprop on<PortableText>.Stega-aware version of
InferComponentsfrom@portabletext/react: the inferred component props cover both clean query results (sanityFetchwithstega: false) and stega-branded results (sanityFetchwhen stega may be enabled), so the samecomponentsobject can render both. Strings that may carry stega payloads stay branded inside component props: render them as-is to keep Visual Editing working, and usestegaCleanon the individual values you compare against string literals.This is useful when working with Sanity TypeGen, where
defineQuery()andsanityFetch()can infer the shape of Portable Text fields.