TypeScript error with react-portabletext block components in NextJS

1 replies
Last updated: Apr 13, 2022
[RESOLVED — See update in the thread]Hi, I have an issue using
react-portabletext component within NextJS/TypeScript project.
When I set up a basic example for block styling as shown in the readme:


const components = {
  block: {
    h1: ({children}) => <h1 className="text-2xl">{children}</h1>,
  }
};

<PortableText value={body} components={components} />
I get the following TypeScript error on the &lt;PortableText&gt; component:


Type '{ block: { h1: ({ children }: { children: any; }) => Element; }; }' is not assignable to type 'Partial<PortableTextReactComponents>'.
  Types of property 'block' are incompatible.
    Type '{ h1: ({ children }: { children: any; }) => Element; }' is not assignable to type 'PortableTextBlockComponent | Record<string, PortableTextBlockComponent>'.
      Type '{ h1: ({ children }: { children: any; }) => Element; }' is not assignable to type 'Record<string, PortableTextBlockComponent>'.
        Property 'h1' is incompatible with index signature.
          Type '({ children }: { children: any; }) => Element' is not assignable to type 'PortableTextBlockComponent'.
            Type '({ children }: { children: any; }) => Element' is not assignable to type 'FunctionComponent<PortableTextComponentProps<PortableTextBlock<PortableTextMarkDefinition, ArbitraryTypedObject | PortableTextSpan, string, string>>>'.
              Types of parameters '__0' and 'props' are incompatible.
                Type 'PropsWithChildren<PortableTextComponentProps<PortableTextBlock<PortableTextMarkDefinition, ArbitraryTypedObject | PortableTextSpan, string, string>>>' is not assignable to type '{ children: any; }'.
                  Property 'children' is optional in type 'PortableTextComponentProps<PortableTextBlock<PortableTextMarkDefinition, ArbitraryTypedObject | PortableTextSpan, string, string>> & { ...; }' but required in type '{ children: any; }'.ts(2322)
[types.ts(32, 3): ]()The expected type comes from property 'components' which is declared here on type 'IntrinsicAttributes & PortableTextProps<any>'
While the front-end still renders fine locally, this is preventing me from deploying the project on Vercel as the build is failing.
Any tips are appreciated.
AI Update

This is a TypeScript type inference issue with @portabletext/react. The error occurs because TypeScript can't properly infer the component prop types when you define the components object inline without explicit typing.

The solution is to explicitly type your components object using the PortableTextReactComponents type from the library:

import { PortableText, PortableTextReactComponents } from "@portabletext/react";

const components: Partial<PortableTextReactComponents> = {
  block: {
    h1: ({children}) => <h1 className="text-2xl">{children}</h1>,
  }
};

<PortableText value={body} components={components} />

By adding the type annotation Partial<PortableTextReactComponents>, you're explicitly telling TypeScript what structure to expect, which resolves the type incompatibility error.

Why This Happens

The issue stems from how TypeScript infers types. When you define the components object without explicit typing, TypeScript infers that children is required based on your component signature ({children}) => .... However, the actual PortableTextComponentProps type from the library makes children optional, creating a type mismatch.

The Partial<PortableTextReactComponents> type tells TypeScript to expect the proper component structure where all props (including children) follow the library's type definitions.

Alternative Approaches

You can also be more specific about the props if you need access to other properties:

import type { PortableTextBlockComponent } from "@portabletext/react";

const components = {
  block: {
    h1: ((props) => <h1 className="text-2xl">{props.children}</h1>) as PortableTextBlockComponent,
  }
};

This pattern is particularly useful when you need to access the full value prop or other properties passed to your custom components, as documented in the @portabletext/react documentation.

The front-end renders fine locally because JavaScript doesn't enforce these type constraints at runtime—it's purely a TypeScript compile-time issue that prevents your Vercel build from succeeding. Adding the explicit type annotation resolves the build failure without changing any runtime behavior.

Show original thread
1 reply
Just an update for anyone who stumbles upon this issue - you can resolve it by specifying the type for the components variable:

import { PortableText, PortableTextReactComponents } from "@portabletext/react";

const components:Partial<PortableTextReactComponents> = {
  block: {
    h1: ({children}) => <h1 className="text-2xl">{children}</h1>,
  }
};
Shouldn’t be required, but works when done this way.

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.

Was this answer helpful?