Skip to content negi.log()

GatsbyJSでmarkdownファイル内のscriptタグを正しく動作させる方法

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を使った上のやり方なら不具合なく動作させることができた。