next-sanity: <SanityLive> strict mode
How to fix the missing includeDrafts prop on SanityLive when using defineLive with strict: true.
When defineLive is configured with strict: true, <SanityLive> requires an explicit includeDrafts prop. TypeScript surfaces an error at compile time if the prop is missing.
Why this happens
With cacheComponents: true in next.config.ts, 'use cache' boundaries cannot call dynamic APIs like draftMode(), so <SanityLive> cannot determine draft mode status on its own. Strict mode enforces explicit passing of this value. When cacheComponents: false (the default), the prop is optional. Strict mode is designed to prepare your app for cacheComponents: true.
Fix
import {SanityLive} from '@/sanity/lib/live'
import {draftMode} from 'next/headers'
export default async function RootLayout({children}: {children: React.ReactNode}) {
const {isEnabled: isDraftMode} = await draftMode()
return (
<html lang="en">
<body>
{children}
<SanityLive includeDrafts={isDraftMode} />
</body>
</html>
)
}includeDrafts={isDraftMode} means live revalidation includes draft content only when draft mode is active, and serves published content to regular visitors.
With Visual Editing
import {SanityLive} from '@/sanity/lib/live'
import {draftMode} from 'next/headers'
import {VisualEditing} from 'next-sanity/visual-editing'
export default async function RootLayout({children}: {children: React.ReactNode}) {
const {isEnabled: isDraftMode} = await draftMode()
return (
<html lang="en">
<body>
{children}
<SanityLive includeDrafts={isDraftMode} />
{isDraftMode && <VisualEditing />}
</body>
</html>
)
}With an embedded Sanity Studio
If the app mounts NextStudio at a route (for example, app/studio/[[...index]]/page.tsx), <SanityLive> must not be in a layout shared with the Studio route. Use route groups to isolate it: place <SanityLive> in src/app/(website)/layout.tsx and keep all non-Studio routes under src/app/(website)/.
Common mistakes
- Rendering
<SanityLive>more than once: only one instance should exist in the component tree. Multiple renders are undefined behavior. - Placing
<SanityLive>in apage.tsx: it belongs in alayout.tsxso it is rendered for every route. - Passing a hardcoded
true: always derive the value fromdraftMode()so published visitors are not served draft content.