Add live content to your application
Moves VisualEditing, defineLive, and isCorsOriginError exports to subpaths
v11.0.0
This major version update introduces changes to how applications must import VisualEditing
, defineLive
, and isCorsOriginError
.
Breaking changes
This release moves the VisualEditing
, defineLive
, and isCorsOriginError
exports to subpaths. This is necessary to allow support for output: static
builds.
These changes are required for all projects updating to next-sanity
v11 or later, regardless if they use static output builds.
Update steps
Update to the latest version of next-sanity
:
npm install next-sanity@latest
pnpm add next-sanity@latest
After installing next-sanity
v11 or higher, update any imports for VisualEditing
, defineLive
, and isCorsOriginError
to use the associated paths instead of the root as shown in the examples below.
VisualEditing
import {VisualEditing} from 'next-sanity/visual-editing' import {SanityLive} from '@/sanity/lib/live' export default function RootLayout({children}: {children: React.ReactNode}) { return ( <html lang="en"> <body> {children} <SanityLive /> {(await draftMode()).isEnabled && <VisualEditing />} </body> </html> ) }
import {VisualEditing} from 'next-sanity' import {SanityLive} from '@/sanity/lib/live' export default function RootLayout({children}: {children: React.ReactNode}) { return ( <html lang="en"> <body> {children} <SanityLive /> {(await draftMode()).isEnabled && <VisualEditing />} </body> </html> ) }
defineLive
Import defineLive
from the next-sanity/live
path.
import {createClient} from 'next-sanity' import {defineLive} from 'next-sanity/live' const client = createClient({ projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID, dataset: process.env.NEXT_PUBLIC_SANITY_DATASET, useCdn: true, apiVersion: 'v2025-03-04', stega: {studioUrl: '/studio'}, }) const token = process.env.SANITY_API_READ_TOKEN if (!token) { throw new Error('Missing SANITY_API_READ_TOKEN') } export const {sanityFetch, SanityLive} = defineLive({ client, serverToken: token, browserToken: token, })
import {createClient} from 'next-sanity' import {defineLive} from 'next-sanity' const client = createClient({ projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID, dataset: process.env.NEXT_PUBLIC_SANITY_DATASET, useCdn: true, apiVersion: 'v2025-03-04', stega: {studioUrl: '/studio'}, }) const token = process.env.SANITY_API_READ_TOKEN if (!token) { throw new Error('Missing SANITY_API_READ_TOKEN') } export const {sanityFetch, SanityLive} = defineLive({ client, serverToken: token, browserToken: token, })
isCorsOriginError
Import isCorsOriginError
from the next-sanity/live
path.
'use client' import {isCorsOriginError} from 'next-sanity/live' import {toast} from 'sonner' export function handleError(error: unknown) { if (isCorsOriginError(error)) { const {addOriginUrl} = error toast.error(`Sanity Live couldn't connect`, { description: `Your origin is blocked by CORS policy`, duration: Infinity, action: addOriginUrl ? { label: 'Manage', onClick: () => window.open(addOriginUrl.toString(), '_blank'), } : undefined, }) } else if (error instanceof Error) { console.error(error) toast.error(error.name, {description: error.message, duration: Infinity}) } else { console.error(error) toast.error('Unknown error', { description: 'Check the console for more details', duration: Infinity, }) } }
'use client' import {isCorsOriginError} from 'next-sanity' import {toast} from 'sonner' export function handleError(error: unknown) { if (isCorsOriginError(error)) { const {addOriginUrl} = error toast.error(`Sanity Live couldn't connect`, { description: `Your origin is blocked by CORS policy`, duration: Infinity, action: addOriginUrl ? { label: 'Manage', onClick: () => window.open(addOriginUrl.toString(), '_blank'), } : undefined, }) } else if (error instanceof Error) { console.error(error) toast.error(error.name, {description: error.message, duration: Infinity}) } else { console.error(error) toast.error('Unknown error', { description: 'Check the console for more details', duration: Infinity, }) } }