1. ホーム
  2. javascript

[解決済み] Reactによるサニティ BlockContentはプレーンテキストのみを表示する

2022-03-05 13:22:09

質問

ポートフォリオサイト用のブログを作成中ですが、Sanity Studioでブログ記事の本文にスタイルを設定しても、そのスタイルが実際のWebサイトに転送されないことに気づきました。ウェブサイトでは、プレーンテキストしか表示されません。これは馬鹿な質問かもしれませんが、私は間違っている何をしているのか見当もつきません。

これが私のSinglePost.jsファイルです。

import { useState, useEffect } from "react";
import { useParams, Link } from "react-router-dom";
import client from "../../client";
import BlockContent from "@sanity/block-content-to-react";
import Header from "../Header";

export default function SinglePost() {
    const [singlePost, setSinglePost] = useState([])
    const [isLoading, setIsLoading] = useState(true)
    const { slug } = useParams()

    useEffect(() => {
        client
          .fetch(
            `*[slug.current == "${slug}"] {
            title,
            body,
            mainImage {
              asset -> {
                _id,
                url
              },
              alt
            }
          }`
          )
          .then((data) => setSinglePost(data[0]))
        setIsLoading(false)
    }, [slug])

    const serializers = {
        types: {
          code: (props) => (
            <pre data-language={props.node.language}>
              <code>{props.node.code}</code>
            </pre>
          ),
        },
      }

    return (
        <div className = "bg-gray-100 dark:bg-zinc-900">
            <Header />
            {isLoading ? ( <h1>Loading...</h1> ) : (
                <section className = "p-5 pb-20 lg:mx-28 md:mx-16 sm:mx-8">
                    <h1 className = "title mb-20">{singlePost.title}</h1>
                    <div className = "flex items-center justify-center">
                        {singlePost.mainImage && singlePost.mainImage.asset && (
                            <img src = {singlePost.mainImage.asset.url} alt = {singlePost.title} title = {singlePost.title} className = "rounded-xl shadow-xl dark:shadow-gray-100/10" />
                            )}
                    </div>
                    <p className = "paragraph mt-5 mb-5">By Brandon Pyle</p>
                    <div className="">
                        <BlockContent serializers={serializers} blocks={singlePost.body} projectId="2hp9gld0" dataset="production" />
                    </div>
                    <button>
                        <Link to = "/blog" className = "button">Read more articles</Link>
                    </button>
                </section>
            )}
        </div>
    )
}

以下は、私のblockContent.jsファイルです。

/**
 * This is the schema definition for the rich text fields used for
 * for this blog studio. When you import it in schemas.js it can be
 * reused in other parts of the studio with:
 *  {
 *    name: 'someName',
 *    title: 'Some title',
 *    type: 'blockContent'
 *  }
 */
export default {
  title: 'Block Content',
  name: 'blockContent',
  type: 'array',
  of: [
    {
      title: 'Block',
      type: 'block',
      // Styles let you set what your user can mark up blocks with. These
      // correspond with HTML tags, but you can set any title or value
      // you want and decide how you want to deal with it where you want to
      // use your content.
      styles: [
        {title: 'Normal', value: 'normal'},
        {title: 'H1', value: 'h1'},
        {title: 'H2', value: 'h2'},
        {title: 'H3', value: 'h3'},
        {title: 'H4', value: 'h4'},
        {title: 'Quote', value: 'blockquote'},
      ],
      lists: [{title: 'Bullet', value: 'bullet'}],
      // Marks let you mark up inline text in the block editor.
      marks: {
        // Decorators usually describe a single property – e.g. a typographic
        // preference or highlighting by editors.
        decorators: [
          {title: 'Strong', value: 'strong'},
          {title: 'Emphasis', value: 'em'},
          {title: 'Code', value: 'code'},
          {title: 'Highlight', value: 'highlight'},
        ],
        // Annotations can be any object structure – e.g. a link or a footnote.
        annotations: [
          {
            title: 'URL',
            name: 'link',
            type: 'object',
            fields: [
              {
                title: 'URL',
                name: 'href',
                type: 'url',
              },
            ],
          },
        ],
      },
    },
    // You can add additional types here. Note that you can't use
    // primitive types such as 'string' and 'number' in the same array
    // as a block type.
    {
      type: 'image',
      options: {hotspot: true},
    },
  ],
}

完全なソースコードはこちらでご覧いただけます。 https://github.com/bpyle02/portfolio このエラーの実例をご覧になりたい方は、私が作成したこのブログ記事をご覧ください。 https://brandonpyle.netlify.app/blog/how-to-properly-write-a-github-readme

解決方法は?

原因を突き止めることができました。このプロジェクトではTailwindCSSを使っているので、ブロックコンテンツに対してスタイルを正しく動作させるためには、Tailwind Typographyプラグインをインストールする必要があります。

このプラグインをインストールするには、次のように入力します。 npm install -D @tailwindcss/typography をコンソールに追加し、さらに require('@tailwindcss/typography'), をtailwind.config.jsファイルのpluginsセクションに追加してください。

次に、BlockContent タグを囲む div に 'prose' クラスを以下のように追加します。

<div className="prose">
    <BlockContent blocks = {singlePost.body} />
</div>

さらに詳しい情報が必要な場合は、Tailwind Docsにあるこのチュートリアルをご覧ください。 https://tailwindcss.com/docs/typography-plugin