sanity-io / block-content-to-react

Deprecated in favor of @portabletext/react
https://github.com/portabletext/react-portabletext
MIT License
161 stars 25 forks source link

"Unknown block type 'text'" error when rendering text from block content field #44

Closed BigglesZX closed 3 years ago

BigglesZX commented 3 years ago

Versions

@sanity/block-content-to-react    2.0.7
react                             17.0.1

Issue

I'm just getting started with Sanity (+ NextJS) so I'm hoping I haven't made a rookie error here. I've started a project from scratch and this part of it deals with content modelling for a simple blog. I'm struggling with an error when trying to output the contents of a custom block field from a blog post.

Here is my (simplified) post document definition:

export default {
    title: 'Post',
    name: 'post',
    type: 'document',
    fields: [
        {
            title: 'Title',
            name: 'title',
            type: 'string',
            validation: Rule => Rule.required(),
        },
        {
            title: 'Content',
            name: 'contentBlocks',
            type: 'contentBlocks',
            validation: Rule => Rule.required(),
        },
    ],
};

Here is the definition for my custom contentBlocks field type (slightly simplified):

export default {
    title: 'Content Blocks',
    name: 'contentBlocks',
    type: 'array',
    of: [
        {
            title: 'Text',
            name: 'text',
            type: 'block',
        },
        {
            title: 'Image',
            name: 'image',
            type: 'image',
            fields: [
                {
                    title: 'Caption',
                    name: 'caption',
                    type: 'string',
                },
            ],
        },
        {
            title: 'Embed',
            name: 'embed',
            type: 'object',
            fields: [
                {
                    title: 'URL',
                    name: 'url',
                    type: 'url',
                    validation: Rule => Rule.required(),
                },
                {
                    title: 'Caption',
                    name: 'caption',
                    type: 'string',
                },
            ],
        },
    ],
};

And my simple Post component looks like this (post is injected by getStaticProps):

import BlockContent from '@sanity/block-content-to-react';
import client from '../client';

const Post = ({ post }) => {
    return (
        <article>
            <h1>{post.title}</h1>
            <BlockContent
                blocks={post.contentBlocks}
                imageOptions={{ w: 320, h: 240, fit: 'max' }}
                {...client.config()}
            />
        </article>
    );
};

However, upon requesting a post document path, I get the following error:

Error: Unknown block type "text", please specify a serializer for it in the `serializers.types` prop

So it seems the BlockContent component is receiving a block of type text (even though, as you can see, none are defined in the field spec) and doesn't know what to do with it. If I inspect the contents of post.contentBlocks, you can see the errant type in there (this is for an example post containing a line of text, an image block, followed by another line of text):

[
  {
    _key: 'fa67a6cc016b',
    _type: 'text',
    children: [ [Object] ],
    markDefs: [],
    style: 'normal'
  },
  {
    _key: '75c4937c4a94',
    _type: 'image',
    asset: {
      _ref: 'image-fe769ba1ea3b199479d317c59a4ac999a4489507-1296x1296-jpg',
      _type: 'reference'
    }
  },
  {
    _key: 'cd3522b721fc',
    _type: 'text',
    children: [ [Object] ],
    markDefs: [],
    style: 'normal'
  }
]

I can solve this error by manually mapping the text type to the standard serializer for block:

BlockContent.defaultSerializers.types.text = BlockContent.defaultSerializers.types.block;

Despite the fix however I still don't understand why this is happening, but I've not found anyone else with the same issue so I'm pretty sure I'm doing something stupid.

I should also note that I've tested existing documents and new documents in case some previous definition was persisting, but the result is the same.

Any suggestions would be much appreciated! Please let me know if I can provide any more information. Thanks!

geball commented 3 years ago

Any success if you get rid of the name and title with type: 'block'?

export default {
  title: 'Content Blocks',
  name: 'contentBlocks',
  type: 'array',
  of: [
    { type: 'block' },
    ...
BigglesZX commented 3 years ago

@geoffreyjball Thanks for the reply – to be honest I think this was likely down to stale data in the dataset as I was making a bunch of schema changes early in the project. I've done several more Sanity + Next.js projects since and the issue has not appeared again. I'll close this and chalk it up to gremlins.