React useState error with LiteYouTubeEmbed in Sanity Portable Text
The error React__namespace.useState is not a function you're encountering is a React version mismatch issue with the react-lite-youtube-embed package, not specifically a Sanity or Portable Text problem. This typically happens in Next.js when a component that uses React hooks isn't properly marked as a Client Component.
The Solution:
Since Next.js 13+ uses the App Router with Server Components by default, you need to mark your CustomPortableText component as a Client Component. Add this directive at the very top of your file:
'use client'
import 'react-lite-youtube-embed/dist/LiteYouTubeEmbed.css'
import { PortableText, PortableTextComponents } from '@portabletext/react'
// ... rest of your importsThe 'use client' directive tells Next.js that this component needs to run on the client side, where React hooks like useState (which LiteYouTubeEmbed uses internally) are available.
Alternative Approach - Split Components:
If you want to keep most of your Portable Text rendering on the server, you can create a separate client component just for the YouTube embed:
// components/YouTubeEmbed.tsx
'use client'
import LiteYouTubeEmbed from 'react-lite-youtube-embed'
import 'react-lite-youtube-embed/dist/LiteYouTubeEmbed.css'
export function YouTubeEmbed({ id, title }: { id: string; title: string }) {
return (
<LiteYouTubeEmbed
aspectHeight={9}
aspectWidth={16}
id={id}
title={title}
/>
)
}Then in your main component:
// No 'use client' needed here
import { YouTubeEmbed } from './YouTubeEmbed'
export function CustomPortableText({ paragraphClasses, value }) {
const components: PortableTextComponents = {
// ... your other components
types: {
youtube: ({ value }) => {
const id = getYouTubeId(value.url)
return <YouTubeEmbed id={id} title={value.alt} />
}
}
}
return <PortableText components={components} value={value} />
}This approach keeps your main Portable Text component as a Server Component while only the YouTube embed runs on the client.
Why This Happens:
The react-lite-youtube-embed library uses React hooks internally, which require the React runtime to be available. In Next.js Server Components, React hooks aren't available because the component is rendered on the server. The error message React__namespace.useState suggests the bundler is having trouble resolving React's exports correctly in a server context.
Your code structure looks correct for rendering Portable Text with custom components in Sanity - this is purely a Next.js Client/Server Component issue!
Show original thread1 reply
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.