1
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.

3kbのHTML to Reactパーサ「DOMParserReact」で、HTML文字列のaタグをNext.jsのLinkコンポーネントで表示する

Last updated at Posted at 2021-10-10

作ったライブラリの宣伝記事です。

DOMParserReactとは

DOMParserReactは軽量なHTML to Reactパーサーです。HTMLテキストをReactのコンポーネントに変換して表示します。また、表示の際にHTMLのタグを任意のコンポーネントに置き換えることができます。

主な使用想定は、個人ブログなどのコンテンツ部分です。コンテンツ部分は、MarkdownのファイルやヘッドレスCMSのリッチテキストで管理し、それをHTMLにしたものを表示していると思います。このライブラリを使用すれば、そのHTMLを表示する際、CSS in JS等のReactの技術を使って装飾したり、タイトルのようにaタグをSPA用の Link コンポーネントに置き換えたりすることができるようになります。

そして、このライブラリの一番の特徴は、その軽さです。minifyで3kb(v0.2.0時点)しかありません。類似ライブラリと比べて非常に軽量なのは、独自のパーサーを使わず、ブラウザJSのAPI DOMParser を使用しているからです。

ライブラリ バンドルサイズ (minify) 備考
dom-parser-react 3kb 筆者作
html-react-parser 27kb
rehype-react 42kb unifiedのプラグイン。計測時は、rehype-reactの他、unified、rehype-dom-parserを使用

※上記は筆者調べ。rollup.jsでバンドルして計測。ただし、react、react-domのサイズは除外

使い方

それでは、実際の使用方法を紹介します。
NPMで公開していますので、インストールは、npm/yarnから行います。

npm i dom-parser-react
# or
yarn add dom-parser-react

DOMParserReactを使用するには、コンポーネントをインポートして変換するHTML文字列を source で指定してください。
そのHTMLを表示するコンポーネントが作成されます。

import DOMParserReact from 'dom-parser-react'
// import { renderToStaticMarkup as render } from 'react-dom/server'

const htmlText = `
  <h1>HTML Text</h1>
`

const App = () =>
  <DOMParserReact source={htmlText} />

render(<App />) // `<h1>HTML Text</h1>`

上記は dangerouslySetInnerHTML と結果がほぼ同じですので、今度はタグを置き換えてみましょう。
components プロパティに { 置換対象のタグ: 置換後のコンポーネント } という形式で指定します。下記は、h1 タグを Title コンポーネントに置き換える例です。

const htmlText = `
  <h1>HTML Text</h1>
`

const Title = (props) =>
  <div className="title">
    <h1 {...props} />
  </div>

const App = () =>
  <DOMParserReact source={htmlText} components={{ h1: Title }} />

render(<App />) // `<div class="title"><h1>HTML Text</h1></div>`

h1div.title で囲まれて表示されました。
今回は囲むだけでしたが、例えば、CSS in JSでスタイリングしたコンポーネントを指定したり、アンカーリンクのアイコン等を追加したりもできます。
また、複数種類のタグを置き換えたい場合は複数記載すれば対応可能です。

const components = {
  h1: Title,
  h2: SubTitle,
  p: Paragraph,
}

<DOMParserReact source={htmlText} components={components} />

Next.jsで使用する

それでは、実際にNext.jsで使用してみましょう。

と言っても、上記のように components を指定するだけです。

import Link from 'next/link'
import DOMParserReact from 'dom-parser-react'

const components = {
  a: ({ href, ...props }) => (
    <Link href={href}>
      <a {...props} />
    </Link>
  ),
}

const Post = ({ htmlText }) =>
  <DOMParserReact source={htmlText} components={components} />

もしかしたら、読者の中には本当に動くか疑問に思っている人がいるかもしれません。最初に説明したように DOMParser はブラウザJSのAPIで、Next.jsのSSR/SSGが実行されるNode.jsにそのAPIはありません。
ですが、DOMParserReactは問題なく動作します。Node.jsでの実行時は、自動でJSDOMというライブラリをインポートし、DOMParser をエミュレートします。これによってブラウザと同じように動作し、SSR/SSGが実行されます。もちろん、ブラウザではJSDOMはバンドルしませんので、軽量なサイズのままです。

最後に

上記の通りこのライブラリは、HTMLコンテンツを簡単に装飾することができ、ライブラリサイズも軽量でSSR/SSGにも対応しています。ぜひ、個人ブログなどに使用してみてください。

おまけ

DOMParserReactを使用した、筆者のブログ

Qiita記事を優先したため、最新の投稿はライブラリ使用前の去年のものになっています。そのうち、DOMParserReact作成時のこととかを書いていきたいです。

1
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
1
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?