作ったライブラリの宣伝記事です。
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>`
h1
が div.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作成時のこととかを書いていきたいです。