4

I've made two iterations of a blog creation experience. The first consisted of an array of different object and document types such as paragraph, gallery, quote, etc while the second, and most recent one, takes advantage of block content to streamline the process. However, I can't get a draft preview using block content to work while it works just fine with the array of components.

Here is the template used for the draft preview:

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

export default ({ pageContext, location }) => {
  const { blogPost = {} } = pageContext;

  return (
    <React.Fragment>
      <BlockContent blocks={blogPost.content} serializers={serializers} />
    </React.Fragment>
  );
};

const serializers = {
  types: {
    block(props) {
      const { style = 'normal' } = props.node;

      if (/^h\d/.test(style)) {
        let className = '';
        const level = style.replace(/[^\d]/g, '');
        switch (level) {
          case '1':
            className = 'domaine--medium-large mt1 mb2';
            break;
          case '2':
            className = 'sans--large mt2 mb1';
            break;
        }

        return (
          <div className="row align--center">
            <div className="col c10--md c7--lg">
              {React.createElement(style, { className }, props.children)}
            </div>
          </div>
        );
      }

      return (
        <div className="row align--center">
          <div className="col c10--md c7--lg">
            {React.createElement(
              style,
              { className: 'sans--medium color--gray-text db mb1 mt1' },
              props.children,
            )}
          </div>
        </div>
      );
    },
  },
};

And then the setup for the blog content in Sanity:

import React from 'react';

/**
 * Defines the structure of a blog post.
 */
export default {
    name: 'blogPost',
    title: 'Blog Post',
    type: 'document',
    fields: [
        {
            name: 'content',
            title: 'Blog Content',
            type: 'blogPortableText'
        },
    ],
};

Now if I go to create a new blog post and populate the Blog Content with anything and press on draft preview, It shows the template from the front end but without the content and in the inspector I get Warning: Failed prop type: The prop blocks is marked as required in SanityBlockContent, but its value is undefined. which is because the block content isn't being passed to the template. Now if I replace the block content with anything else such as just a text component the preview works fine and it seems the problem is just the block content.

diedu
  • 19,277
  • 4
  • 32
  • 49
Mr.Smithyyy
  • 2,157
  • 12
  • 49
  • 95
  • You question description lacks detail. How is your `Preview` component connected with `blogPost` schema? I skim through the doc and from my understanding at least the `preview` property should present in the schema, am I right? – hackape Sep 26 '20 at 08:51
  • The `sanity` framework looks quite neat, but it's quite far away from being a popular framework. I for one hear of it for the first time. So it'd be a lot easier if you can provide a code repo to show case your problem, with minimal setup, so people can `npm install` and `npm start` and start diagnosing. Currently I can only guess. – hackape Sep 26 '20 at 08:55
  • Can you somehow reproduce this issue on http://codesandbox.io? @Mr.Smithyy – 95faf8e76605e973 Sep 30 '20 at 23:33

1 Answers1

2

@hackape is definitely asking a question I'd like the answer to as well. How is the pageContext being supplied?

One thing I'm seeing is the it looks like in your destructuring of pageContext, blogPost might not be defined and you're providing a default value of an empty object.

This would mean that blogPost.content would be undefined which explains your error.

You could provide a better default value such as { content: '' } or you could choose to not render the <BlockContent /> until you have a content value:

const { blogPost = { content: '' } } = pageContext

if (blogPost.content !== undefined) {
    return <BlockContent blocks={blogPost.content} serializers={serializers} />
}

return null
ArrayKnight
  • 6,956
  • 4
  • 17
  • 20
  • Sorry that this isn't actually a complete answer to your question. It's just that there's a character limit on the comments... If you provide further details, I'll work on editing my answer to help provide a more thorough solution – ArrayKnight Sep 29 '20 at 20:08