19
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

NIJIBOXAdvent Calendar 2022

Day 3

microCMS + React に highlight.js を適用させたときの話

Last updated at Posted at 2022-12-02

こんにちは!クリスマスがやってきますね:santa_tone2::evergreen_tree:

アドカレ3日目は、microCMSのリッチエディタへ書かれたコードに(まるで街のイルミネーションのように)色をつけたく、言語に合わせてハイライトを入れたときのことについて書いていきます。

※ この記事では、microCMS、React、nodeモジュール(html-react-parser、highlight.js)を扱っています。

microCMSのリッチエディタに書かれた文章について

リッチエディタ(コンテンツを入力するフィールドの一つ)に文章を入力して、その記述を取得すると文字列になったDOMが返ってきます。

例1)
入力時:こんにちは
取得時:<p>こんにちは</p>

例2)
入力時:

p { color: #555; };

取得時:<pre><code>p { color: #555; };</code></pre>

取得した文字列をパースする

ハイライトをつける前に、文字列ではなくDOM要素として扱ってもらうためにパースします。パースしない場合、文字列としてそのまま表示されることになます。

直接文字列を入れてパースする例

// 画面表示されるもの → Hello, World!
import parse from 'html-react-parser'
parse('<p>Hello, World!</p>')

microCMSから取得した文字列をパースしたときの例

// contentHTMLにmicroCMSのリッチエディタから取得した文字列が入っている
import parse from 'html-react-parser'

export default function ConvertText({ contentHTML }) {
  const contentReact = parse(contentHTML)
  return <>{contentReact}</>
}

パースする記述の中でcode要素を検知する

リッチエディタでコードブロックを用いて記述したものは、code要素で囲まれます。そのcode要素であるDOMを検知することで、ハイライトする処理につなげます。
import parse from 'html-react-parser'

export default function ConvertText({ contentHTML }) {
  const contentReact = parse(contentHTML, {
    // 以下で検知
    replace: (node) => {
      if(node.name === 'code') {
        // ハイライト処理を入れる場所
      }
    }
  })
  return <>{contentReact}</>
}

code内にハイライトを入れて、完成

code要素の子要素にhighlight.jsを適用させ、その適用させたDOM要素をパースします。以上でハイライトまでの処理は完成です。
import parse from 'html-react-parser'
import hljs from 'highlight.js'
import 'highlight.js/styles/hybrid.css';

export default function ConvertText({ contentHTML }) {
  const contentReact = parse(contentHTML, {
    replace: (node) => {
      if(node.name === 'code') {
        const result = hljs.highlightAuto(node.children[0].data);
        const dom = parse(result.value);
        
        return (
          <code className='hljs'>
            {dom}
          </code>
        )
      }
    }
  })
  return <>{contentReact}</>
}

highlight.js
highlightAuto関数を用いて言語の種類を検知し、コードに色をつけるために要素とクラスを付与
highlight.js/styles/hybrid.css
コードに色をつける際のテーマ。使うテーマのみインポートする。テーマは公式サイト参照
公式サイト:https://highlightjs.org/static/demo/

〜 highlight.jsを使った理由 〜

そもそもコードブロックに記述する時点で何の言語か指定し、ブラウザでの表示時に自動で配色されると楽でしたが、microCMSには試していたときにはその機能はないことがわかったので、ハイライトをつけられる方法を探していました。そこでPrism.jsの使用を考えたのですが、何の言語か実装側で指定しないとスタイルをつけることができなかったので、どんな言語かわからないけど検知してハイライトをつけてくれるhighlight.jsにすることにしました。

最後に

何かのお役に立てたら幸いです、メリークリスマス!!:snowman:

19
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?