GatsbyJSでmarkdownファイルをparseするにはgatsby-transformer-remarkが一般的だろう。 本ブログもgatsby-transformer-remarkを使用している。
gatsby-transformer-remarkを使うとmarkdownファイルからHTMLのテキストを取得できる。 取得したHTMLのテキストをdangerouslySetInnerHTMLpropsにわたすことで、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を使った上のやり方なら不具合なく動作させることができた。