GatsbyJSでmarkdownファイルをparseするにはgatsby-transformer-remarkが一般的だろう。 本ブログもgatsby-transformer-remarkを使用している。
gatsby-transformer-remarkを使うとmarkdownファイルからHTMLのテキストを取得できる。 取得したHTMLのテキストをdangerouslySetInnerHTML
propsにわたすことで、HTMLのテキストをHTMLDOMとして表示させる。
このときdangerouslySetInnerHTML
に渡されたHTMLのテキストに<script>
タグが含まれていた場合は無視するしようになっている。 そのため、markdownファイルに記載した<script>
タグは正しく動作しない。
どうやってこれを回避するかというとreact-helmetを使う。 react-helmetを使うと<head>
内の要素を動的に変えることができる。 <script>
タグをHTMLのテキストから抽出して、抽出した<script>
タグをreact-helmetを使って動的に<head>
内に挿入すればよい。
console.log(html) // htmlファイルのテキスト
const scriptTagRegExp = /<script.*>.*<\/script>/g // <script>タグにマッチする正規表現
const scriptTagList = html.match(scriptTagRegExp) // htmlからscriptタグのリストを取得
const htmlExcludingScriptTag = html.replace(scriptTagRegExp, '') // <scriptタグ>をhtmlから排除する
return (
<>
<Helmet> {/* <head>に<script>タグを追加 */}
{scriptTagList?.map(stringScriptTag => {
return parse(stringScriptTag))
})}
</Helmet>
<div dangerouslySetInnerHTML={htmlExcludingScriptTag} />
</>
これ以外のやり方も色々試したが、画面が遷移すると正しく動かなかったりscriptが重複して読まれたりとうまく動作できなかった。 react-helmetを使った上のやり方なら不具合なく動作させることができた。