How AI is powering better personalization in e-commerce [with Vercel]. Sign up now

Why does PortableText need dataset and projectId props if sanity.json exists?

8 repliesLast updated: Nov 29, 2025

Hi, I am using
PortableText
but I am wondering why is the dataset, projectId necessary when you hava projectId and dataset in the sanity.json file.

<PortableText
            dataset={process.env.NEXT_PUBLIC_SANITY_DATASET!}
            projectId={process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!}
            content={post.body}
            serializers={{
              h1: (props: any) => (
                <h1 className="text-2xl font-bold my-5" {...props} />
              ),
              h2: (props: any) => (
                <h2 className="text-xl font-bold my-5" {...props} />
              ),
              h3: (props: any) => (
                <h3 className="text-lg font-bold my-5" {...props} />
              ),
              h4: (props: any) => (
                <h4 className="text-md font-bold my-5" {...props} />
              ),
              blockquote: (props: any) => (
                <blockquote
                  className="text-xl text-red-300 font-bold my-5"
                  {...props}
                />
              ),
              li: ({ children }: any) => (
                <li className="ml-4 list-disc">{children}</li>
              ),
              link: ({ href, children }: any) => (
                <a href={href} className="text-blue-500 hover:underline">
                  {children}
                </a>
              ),
            }}
          />

AI Update

Good question! The projectId and dataset props on the PortableText component are specifically needed for rendering images (and other assets like files) that are embedded in your Portable Text content.

When your Portable Text contains images, the component needs to construct proper image URLs using Sanity's image URL builder. To generate these URLs, it needs to know which Sanity project and dataset to pull the images from. The component can't automatically read from your sanity.json or sanity.config.ts file because it's a standalone React component that doesn't have access to your Sanity configuration.

Here's what's happening behind the scenes:

When you have an image block in your Portable Text, the component needs to transform the image reference (which is just metadata) into an actual URL like:

https://cdn.sanity.io/images/{projectId}/{dataset}/{imageId}-{dimensions}.{format}

However, if your Portable Text content doesn't contain any images or file references, you technically don't need to pass these props. But it's good practice to include them anyway in case you add images to your content later.

If you want to avoid repeating these props everywhere, you have a few options:

// components/MyPortableText.tsx
import { PortableText } from '@portabletext/react'

export function MyPortableText({ content, serializers }) {
  return (
    <PortableText
      value={content}
      components={serializers}
      projectId={process.env.NEXT_PUBLIC_SANITY_PROJECT_ID}
      dataset={process.env.NEXT_PUBLIC_SANITY_DATASET}
    />
  )
}

Note: The prop should be value={post.body} (not content) and components (not serializers) if you're using the modern @portabletext/react library, though it looks like your code might be using an older version where those prop names were different.

Show original thread
8 replies

Was this answer helpful?

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.

Related contributions