Mr.Smithyyy
Mr.Smithyyy

Reputation: 1329

Sanity draft preview not working with block content

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.

Upvotes: 4

Views: 1883

Answers (1)

ArrayKnight
ArrayKnight

Reputation: 7356

@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

Upvotes: 2

Related Questions