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.

3
  • 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, 2020 at 8: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, 2020 at 8:55
  • Can you somehow reproduce this issue on codesandbox.io? @Mr.Smithyy Sep 30, 2020 at 23:33

1 Answer 1

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
1
  • 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 Sep 29, 2020 at 20:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.