こもるーとたぬきの備忘録

profile

【React】react-syntax-highlighterをhtml-react-parserのreplaceオプションに組み込んだ話

Highlight.jsを使用して、ブログ内のコードを表示していたが、React特有のコードがうまく表示されなかった。

表示が崩れた
表示が崩れた

色々調べていたら、Highlight.jsとPrismそれぞれをサポートしていてかつ、Reactの対応もしているreact-syntax-highlighter の方が良さそうだと思い、Hightlight.jsからreact-syntax-highlighterに乗り換えることにした。 この記事ではその作業手順をまとめる。

開発環境

開発環境バージョン
Next.js15.1.2
TypeScript5.0.0
sass1.83.0

作業内容

react-syntax-highlighterと@types/react-syntax-highlighter をインストール

react-syntax-highlighter@types/react-syntax-highlighterを以下のコマンドでインストール


    npm install --save @types/react-syntax-highlighter 
    npm install --save react-syntax-highlighter
    

@types/react-syntax-highlighterは、react-syntax-highlighterの型定義をしているパッケージ
私はtypeScriptを環境に入れているので、インストールした。

html-react-parserのreplaceオプションにreact-syntax-highlighterを組み込む。

html-react-parserは、HTML文字列をReact要素に変換してくれるパッケージ。
replaceオプションを使用すると要素を別の要素に変換させることができる。
記事本文の中から、


    <div class="code" language="{言語指定}">
    {表示させたいコード}
    </div>
    

のタグを検出することができた場合に、検出したタグの中身をreact-syntax-highlighterに適用させる。 以下、その処理


    import SyntaxHighlighter from "react-syntax-highlighter";
    import parse, {
            HTMLReactParserOptions,
            Element,
            DOMNode,
        } from "html-react-parser";
    import { atelierSeasideLight } from "react-syntax-highlighter/dist/cjs/styles/hljs";

    const options: HTMLReactParserOptions = {
        replace(domNode: DOMNode) {

            if (domNode instanceof Element && domNode.attribs.class === "code") {
            const language = domNode.attribs?.language;
            const node = domNode.childNodes[0] as Node;

                return (
                <SyntaxHighlighter language={language} style={atelierSeasideLight}>
                    {node.data}
                </SyntaxHighlighter>
                );
            }

        },
    };
    
表示が治った
表示崩れが解消された

作業完了

備考

参考