Sanity code-input plugin: Cannot read properties of undefined (reading 'code')

7 replies
Last updated: Jul 24, 2023
Hey guys, using NextJS 13.4, Sanity v3, and tailwind to make a personal blog. Everything's working just fine, except for the code-input plugin.
I've followed all of the steps.

1. I've installed the plugin just fine
2. I've added the plugin to sanity.config.js
3. Ive added all the needed schemas

...other stuff,
{
  name: 'content',
  title: 'Content',
  type: 'array',
  of: [
  {
    type: 'block',
  },
  {...other types of content here, eg. images etc.},
  {
    name: "code",
    title: "Code Block",
    type: "code",
    options: {
      withFilename: true, // optional
      highlightedLines: true, // optional
    },
  }
  ]
} 
4. I'm stuck at properly passing my RichTextComponent.jsx. All other styles within this component work just fine. The only style that doesn't work is the code one, shown below:

export const RichTextComponents = {
  types: {

//BIG PROBLEMS HERE!!!
    code: ({ data }) => {
      const code = data.code;
      const filename = data.filename;
      const language = data.language;

      return (
        <div>
          <div className="flex justify-between ">
            <p className="opacity-70">{filename}</p>
            <p>
              language: <span className="opacity-70">{language}</span>
            </p>
          </div>
          <pre className="p-2">
            <code>
              {/* this method has no syntax highlighting,
            look below for that */}
              {code}
            </code>
          </pre>
        </div>
      );
    },
  },
///END OF PROBLEMS ABOVE


//image type working just fine
//block, list, marks, etc working just fine//
};
This is how I'm passing the RichTextComponent props on the blog page:

      <div className="px-2 prose prose-lg my-2text-justify mx-auto">
        <PortableText value={blog.body} components={RichTextComponents} />
      </div>
Below is the error I get:

error - components\RichTextComponents.jsx (28:24) @ code
error - TypeError: Cannot read properties of undefined (reading 'code')
    at code (./components/RichTextComponents.jsx:38:31)
    at stringify (<anonymous>)
  26 |     },
  27 |     code: ({ data }) => {
> 28 |       const code = data.code;
     |                        ^
  29 |       const filename = data.filename;
  30 |       const language = data.language;
  31 | 
error - components\RichTextComponents.jsx (28:24) @ code
error - TypeError: Cannot read properties of undefined (reading 'code')
    at code (./components/RichTextComponents.jsx:38:31)
Can anybody please help?
AI Update

Looking at your error, the issue is that you're using data to access the code properties, but with Portable Text in Sanity v3, the correct property is value, not data.

The code-input plugin stores its content in a specific structure, and when you're rendering it through PortableText, you need to access it via value.code, value.filename, and value.language.

Here's the corrected version of your RichTextComponents:

export const RichTextComponents = {
  types: {
    code: ({ value }) => {  // Changed from 'data' to 'value'
      const code = value.code;
      const filename = value.filename;
      const language = value.language;

      return (
        <div>
          <div className="flex justify-between ">
            <p className="opacity-70">{filename}</p>
            <p>
              language: <span className="opacity-70">{language}</span>
            </p>
          </div>
          <pre className="p-2">
            <code>
              {code}
            </code>
          </pre>
        </div>
      );
    },
  },
  // ...rest of your components
};

The key change is ({ data })({ value }). This is the standard way custom types are passed to serializers in @portabletext/react, which is what the <PortableText> component uses under the hood.

If you want to add syntax highlighting (which you mentioned in your comment), you could integrate a library like Prism or react-syntax-highlighter:

import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { vscDarkPlus } from 'react-syntax-highlighter/dist/cjs/styles/prism';

code: ({ value }) => {
  return (
    <div>
      {value.filename && (
        <div className="flex justify-between bg-gray-800 px-4 py-2 text-sm text-gray-300">
          <p>{value.filename}</p>
          <p>language: <span className="opacity-70">{value.language}</span></p>
        </div>
      )}
      <SyntaxHighlighter language={value.language} style={vscDarkPlus}>
        {value.code}
      </SyntaxHighlighter>
    </div>
  );
}

That should fix your error and get your code blocks rendering properly!

Show original thread
7 replies
Hey Walid,
I've copied your code, but one thing that is different, is that where you're using
data
in
RichTextComponent.jsx
, I'm using
value
. If I use
data
, I can duplicate your error message, but
value
fixes it.

code: ({ value }) => {
	console.log('value: ', value)

	const code = value.code;
	const filename = value.filename;
	const language = value.language;

	return (
		<div>
			<div className="flex justify-between ">
				<p className="opacity-70">{filename}</p>
				<p>
					language: <span className="opacity-70">{language}</span>
				</p>
			</div>
			<pre className="p-2">
				<code>
					{/* this method has no syntax highlighting,
look below for that */}
					{code}
				</code>
			</pre>
		</div>
	);
},
Thank you! It works!
But I am so frustrated as to
why it works! Haha. Why "value"? Where is that written?
Perfect! Well, at least the blocker is removed!
The reason that it works is found in your
node-modules
. Specifically:

node_modules > @portabletext > react > dist > react-portable-text.d.ts
On around line 120 (depending on version, of course), where it declares the interface
PortableTextMarkComponentProps
, it's looking for
value
.
Thank you KJ. I really need to move to TypeScript.
No problem, and let us know if there's anything we can do to help! Learning TS is a bit of a process, but once it clicks (and it does eventually click), it makes a lot of sense.
Thanks Kj! Is there a directory of other types I could use? Highlighting, etc? I've successfully added images and codeblocks so far.
There's not an official directory that I know of, but there are a few ideas in the article about Configuring the Portable Text Editor . In addition to that, there are a lot of things out in the wild that people have created. That's the really cool thing about it - how customizable it is - but that's also why there's not a definitive catalogue. A few that I have used in the past include a horizontal rule, and various text decorators including colours, and highlighting.

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?