Skip to main content
The preview system provides utilities for rendering document previews and subscribing to preview data throughout the Studio.

DocumentPreviewStore

The document preview store manages subscriptions to document data for preview purposes. Documents observed by this store receive real-time updates but don’t support optimistic updates.
import {useDocumentPreviewStore} from 'sanity'

function MyComponent() {
  const previewStore = useDocumentPreviewStore()
  // Use preview store methods
}

observeForPreview

Observe a document’s preview data:
import {useDocumentPreviewStore} from 'sanity'
import {useEffect, useState} from 'react'

function DocumentPreview({documentId, schemaType}: Props) {
  const previewStore = useDocumentPreviewStore()
  const [preview, setPreview] = useState(null)
  
  useEffect(() => {
    const subscription = previewStore
      .observeForPreview({_id: documentId}, schemaType)
      .subscribe(setPreview)
    
    return () => subscription.unsubscribe()
  }, [documentId, schemaType, previewStore])
  
  return <div>{preview?.title}</div>
}
value
Previewable
required
Document or reference to preview
type
PreviewableType
required
Schema type or type object
options
object
Preview options
viewOptions
PrepareViewOptions
Options for the preview preparation
perspective
StackablePerspective[]
Perspective stack for queries
observable
Observable<PreparedSnapshot>
Observable that emits prepared preview snapshots
snapshot
object
Prepared preview data
title
string
Preview title
subtitle
string
Preview subtitle
description
string
Preview description
media
ReactNode
Preview media (image, icon, etc.)

observePaths

Observe specific paths in a document:
previewStore.observePaths(
  {_id: 'article-123'},
  ['title', 'slug.current', 'author.name']
)
value
Previewable
required
Document or reference
paths
string[]
required
Array of paths to observe (e.g., ['title', 'author.name'])
observable
Observable<any>
Observable that emits the document with requested paths

Preview Components

SanityDefaultPreview

Default preview component for documents:
import {SanityDefaultPreview} from 'sanity'

function DocumentItem({document, schemaType}: Props) {
  return (
    <SanityDefaultPreview
      value={document}
      schemaType={schemaType}
      layout="default"
    />
  )
}
value
SanityDocument
required
Document to preview
schemaType
SchemaType
required
Schema type definition
layout
'default' | 'card' | 'media' | 'detail'
Preview layout style. Default: 'default'
status
ReactNode
Status indicator to display

Preview

Generic preview component:
import {Preview} from 'sanity'

function CustomPreview({documentId, schemaType}: Props) {
  return (
    <Preview
      value={{_id: documentId}}
      schemaType={schemaType}
      layout="card"
    />
  )
}
value
Previewable
required
Value to preview (document, reference, or value with preview config)
schemaType
SchemaType
required
Schema type
layout
'default' | 'card' | 'media' | 'detail'
Layout style

PreviewLoader

Lazy-loading preview component:
import {PreviewLoader} from 'sanity'

function LazyPreview({documentId, schemaType}: Props) {
  return (
    <PreviewLoader
      value={{_id: documentId}}
      schemaType={schemaType}
    >
      {(preview) => (
        <div>
          <h3>{preview.title}</h3>
          <p>{preview.subtitle}</p>
        </div>
      )}
    </PreviewLoader>
  )
}
value
Previewable
required
Value to preview
schemaType
SchemaType
required
Schema type
children
function
required
Render function that receives prepared preview

Preview Utilities

getPreviewPaths

Extract preview paths from schema type:
import {getPreviewPaths} from 'sanity'

const paths = getPreviewPaths(schemaType)
// Returns: ['title', 'subtitle', 'media']
schemaType
SchemaType
required
Schema type to extract paths from
paths
string[]
Array of field paths used in preview

prepareForPreview

Prepare a value for preview:
import {prepareForPreview} from 'sanity'

const prepared = prepareForPreview(
  document,
  schemaType,
  {selection: ['title', 'author']}
)
value
any
required
Value to prepare
schemaType
SchemaType
required
Schema type
options
PrepareViewOptions
Preparation options
prepared
PreparedSnapshot
Prepared preview data with title, subtitle, description, and media

getPreviewValueWithFallback

Get preview value with fallback:
import {getPreviewValueWithFallback} from 'sanity'

const preview = getPreviewValueWithFallback({
  value: document,
  schemaType,
})
value
any
required
Value to get preview for
schemaType
SchemaType
required
Schema type
preview
PreparedSnapshot
Preview with fallback values for missing fields

useValuePreview

Hook to observe preview data:
import {useValuePreview} from 'sanity'

function DocumentCard({document, schemaType}: Props) {
  const {value, isLoading} = useValuePreview({
    value: document,
    schemaType,
  })
  
  if (isLoading) return <div>Loading...</div>
  
  return (
    <div>
      <h3>{value.title}</h3>
      <p>{value.subtitle}</p>
    </div>
  )
}
value
any
required
Value to preview
schemaType
SchemaType
required
Schema type
result
object
Preview result
value
PreparedSnapshot
Prepared preview data
isLoading
boolean
Whether the preview is loading
error
Error | null
Error if preview failed to load

Example: Custom Preview List

import {useValuePreview, useClient} from 'sanity'
import {Card, Stack, Text} from '@sanity/ui'
import {useEffect, useState} from 'react'

function DocumentList({schemaType}: {schemaType: string}) {
  const client = useClient({apiVersion: '2024-01-01'})
  const [documents, setDocuments] = useState([])
  
  useEffect(() => {
    client
      .fetch(`*[_type == $type][0...10]`, {type: schemaType})
      .then(setDocuments)
  }, [client, schemaType])
  
  return (
    <Stack space={2}>
      {documents.map(doc => (
        <DocumentPreviewCard 
          key={doc._id} 
          document={doc}
          schemaType={schemaType}
        />
      ))}
    </Stack>
  )
}

function DocumentPreviewCard({document, schemaType}: Props) {
  const schema = useSchema()
  const type = schema.get(schemaType)
  const {value, isLoading} = useValuePreview({value: document, schemaType: type})
  
  if (isLoading) return <Card padding={3}>Loading...</Card>
  
  return (
    <Card padding={3} radius={2} shadow={1}>
      <Stack space={2}>
        <Text weight="bold">{value.title}</Text>
        {value.subtitle && <Text size={1} muted>{value.subtitle}</Text>}
      </Stack>
    </Card>
  )
}

Build docs developers (and LLMs) love