ブログトップ画像

microCMSのリッチエディタ(生HTML)をReactのコンポーネントにパースしてみた

フロントエンド

概要

microCMS ではブログなどの記事データをリッチエディタで入稿することが可能です。ただ、APIではそれらが生HTMLで返ってきます。

dangerouslySetInnerHTML に渡せばレンダリングされますが、以下のようなケースもあると思います。

  • Chakra UI などの定義されているコンポーネントを利用したい
  • class指定してグローバルCSSを書きたくない
  • XSSの危険性があるからdangerouslySetInnerHTMLを利用したくない


今回はこれらを解決するhtml-react-parserを利用していきます。サンプルコードはこちら。microCMSの取得処理は省略しています。

実行環境

サンプルとして、Next.jsChakra UI を利用します。

html-react-parserとは

html-react-parser はReactで生HTMLを自由に加工することが可能になります。例としては、以下のように生HTMLをReactのコンポーネントに変換できます。

parse('<p id="replace">text</p>', {
  replace: domNode => {
    if (domNode.attribs && domNode.attribs.id === 'replace') {
      return <Text>replaced</Text>;
    }
  }
});


microCMSのリッチエディタ(生HTML)に対応

それでは、microCMSのリッチエディタ(生HTML)に対応していきます。

インストール

公式を参考にインストールしてください!

リッチエディタ(生HTML)をコンポーネントにパース

コンポーネントを以下のように定義し、parseの処理を追加します。

export const Markdown = (): JSX.Element => {
  return (
    <Box >
      {parse(source, options)}
    </Box>
  );
};


次にparse のoptionsについて説明します。optionsには、replace domToReactを利用します。replaceはある要素をコンポーネントへ置き換えることができます。domToReactはその要素の子要素も再起的にコンポーネントへ置き換えることができます。

サンプルでh1だと、下記でコンポーネントに変換が可能です。こんな感じで良しなに変換内容の定義ができます。以上です。

const options: HTMLReactParserOptions = {
  replace: (domNode) => {
    if (domNode instanceof Element && domNode.type === 'tag') {
      const props = attributesToProps(domNode.attribs);

      if (domNode.attribs && domNode.name === 'h1') {
        return (
          <Text as='h1' {...props}>
            {domToReact(domNode.children, options)}
          </Text>
        );
      }
     ...
    }
  },
};


まとめ

microCMSのリッチエディタ(生HTML)をコンポーネントに変換する方法をご紹介しました。生HTMLを自由に加工出来ると拡張性が高くなるので良いですね。(このブログも対応したい)