How to generate massive amounts of demo content for Sanity
It can be useful for testing plugins, front ends, or other integrations to have a Sanity Studio populated with fake content.
Go to How to generate massive amounts of demo content for SanityWhen setting up live preview, you may create unique components to perform live queries. However, it might be more convenient in a larger application to reuse a single wrapper component that can perform a query and pass live-updating content to any child component.
If you’re setting up live preview for the first time, start with one of these guides:
The guides above walk through how to set up these client libraries:
Assumptions:
@sanity/preview-kit
already configuredThe code examples below are taken from a Next.js App router project and some include the ‘use client’
directive. You can safely remove these lines from the code examples for frameworks that do not yet support React Server Components.
preview-kit
now exports a <LiveQuery>
wrapper component which does the same thing as shown in this guide. Use it, or continue on if you'd prefer to do it yourself!
PreviewWrapper
which will take the initial data you initially fetch server-side.PreviewWrapper
component will prop-drill that initial data unless preview mode is active and a query is supplied.Traditionally you could use “render props” and pass a rendering function to render either published or preview content conditionally. However, passing functions from server to client is not currently possible with React Server components. The technique shown in this guide relies on conditionally loaded components that prop-drill published or preview content to their child component.
The "Course Platform Demo" is a Sanity Studio and Next.js App router application that uses this method to reuse the PreviewWrapper
component in every route to make each unique layout automatically update with live preview.
Note: It is predominately a demonstration of internationalization strategies with Sanity and is not intended as a starter template for new projects.
The magic of this approach is handled by @radix-ui/react-slot
, which enables components to pass props to their direct children, no matter what they are.
Install it to your front-end project:
npm install @radix-ui/react-slot
Create a new component file for PreviewWrapper
, which will wrap the component you use to render Sanity content:
// PreviewWrapper.tsx
import {Slot} from '@radix-ui/react-slot'
import {QueryParams} from '@sanity/client'
import {PropsWithChildren} from 'react'
import {PreviewData} from '@/components/PreviewData'
type PreviewWrapperProps<T> = PropsWithChildren<{
initialData: T
preview?: boolean
query?: string
params?: QueryParams
}>
// Component just renders its children if preview mode is not enabled
export function PreviewWrapper<T>(props: PreviewWrapperProps<T>) {
const {
// Is preview mode active?
preview = false,
// If so, listen to this query
query = null,
// With these params
params = {},
// Separate remaining props to pass to the child
...rest
} = props
// Render child, with the wrapper's initial data and props
if (!preview || !query) {
const nonPreviewProps = {...rest, data: props.initialData}
return <Slot {...nonPreviewProps} />
}
// Swap initialData for live data
return (
<PreviewData<typeof props.initialData>
initialData={props.initialData}
query={query}
params={params}
>
{props.children}
</PreviewData>
)
}
Create the PreviewData
component file:
// PreviewData.tsx
'use client'
import {Slot} from '@radix-ui/react-slot'
import {QueryParams} from '@sanity/client'
import {useLiveQuery} from '@sanity/preview-kit'
import {PropsWithChildren} from 'react'
type PreviewDataProps<T = any> = PropsWithChildren<{
initialData: T
query: string
params: QueryParams
}>
// Browser-only preview component
export function PreviewData<T = any>(props: PreviewDataProps<T>) {
const {initialData, query, params = {}, ...rest} = props
const [data] = useLiveQuery(initialData, query, params)
const previewProps = {...rest, data}
return <Slot {...previewProps} />
}
Here is an example of a Next.js route using these preview wrapper components.
Take note that:
getClient
function is returning a specific version of Sanity client with the correct perspective configured so that the initial data is either published
or previewDrafts
– without this step, you may see an initial flash of published content before live preview updates to draft contentPreviewWrapper
and passed to the useLiveQuery()
hookPresenterLayout
component does not have any props, because PreviewWrapper
will handle passing them down either from initialData
or live updating content as a prop named data
PreviewWrapper
should expect to receive a data
prop with the published or draft Sanity content// ./app/presenter/[slug]/page.tsx
import {draftMode} from 'next/headers'
import {presenterQuery} from '@/sanity/queries'
import {getClient} from '@/sanity/client'
export default async function PresenterPage({params}) {
const {isEnabled: preview} = draftMode()
const data = await getClient(preview).fetch(presenterQuery, params)
return (
<PreviewWrapper
preview={preview}
initialData={data}
query={presenterQuery}
params={params}
>
<PresenterLayout />
</PreviewWrapper>
)
}
Here is a truncated example of what the PresenterLayout
component might look like, receiving the Sanity Content in the data
prop:
type PresenterLayoutProps = {
data?: {
name?: string
title?: string
}
}
export default function PresenterLayout(props: PresenterLayoutProps) {
if (!props.data) {
console.log(`PresenterLayout data empty: ${JSON.stringify(props)}`)
return null
}
const {name, title} = props.data
return <div>{name}: {title}</div>
}
That's it! You should now be able to use your PreviewWrapper
component to wrap any component that expects to receive a data
prop – and whether you are in preview mode or production, see the expected layout with the right content.
Sanity Composable Content Cloud is the headless CMS that gives you (and your team) a content backend to drive websites and applications with modern tooling. It offers a real-time editing environment for content creators that’s easy to configure but designed to be customized with JavaScript and React when needed. With the hosted document store, you query content freely and easily integrate with any framework or data source to distribute and enrich content.
Sanity scales from weekend projects to enterprise needs and is used by companies like Puma, AT&T, Burger King, Tata, and Figma.
It can be useful for testing plugins, front ends, or other integrations to have a Sanity Studio populated with fake content.
Go to How to generate massive amounts of demo content for SanityPreview draft content and changes as-you-type in Next.js from Sanity Studio
Go to Live Preview with Next.js App Router and Sanity StudioSummarise form progression by decorating the entire editing form for a document with a component loaded at the root level.
Go to Create a document form progress componentObject types use a preview property to display contextual information about an item when they are inside of an array; customizing the preview component can make them even more useful for content creators.
Go to Create richer array item previews