🧪

Jekyll × Commonmarker で iframe タグがレンダリングされない問題の解決法

に公開

前菜

jekyll-commonmark-ghpages の README を見ると以下のような設定を _config.yml に追加する方法が紹介されています。

commonmark:
  options: ["UNSAFE", "SMART", "FOOTNOTES"]
  extensions: ["strikethrough", "autolink", "table", "tagfilter"]

しかしこれだと iframe が正しく表示されなくなるという問題が発生しました。

タグがそのまま表示されてしまいます。

メインディッシュ

これの解決策はシンプルで、tagfilter を削除します。

commonmark:
  options: ["UNSAFE", "SMART", "FOOTNOTES"]
  extensions: ["strikethrough", "autolink", "table"]

これで iframe が表示されるようになりました。

iframe を表示させる方法

そもそもセキュリティ上の観点から、デフォルトでは Jekyll でビルドした記事の中の iframe はサニタイズされ表示されません。

それを表示するためのオプションが、Commonmarker では UNSAFE です。これをつけることで iframe が表示されるようになります。

commonmark:
  options: ["UNSAFE"]

Render options

HTML タグをそのまま表示させる方法

一方で、HTML タグをそのまま表示させる拡張も用意されています。これが冒頭で登場した tagfilter です。

commonmark:
  extensions: ["tagfilter"]

Extension options

これを追加すると、<&lt; に、>&gt; にそれぞれエスケープされるため、たとえば <iframe> と書いてあると &lt;iframe&gt; と変換され、ページ上では <iframe> のようにそのまま文字として表示されることになります。

Disallowed Raw HTML (extension) | GitHub Flavored Markdown Spec

つまり、UNSAFEtagfilter を同時に指定すると、せっかく UNSAFEiframe が表示されるようになったのに、それをただのタグとしてそのまま表示してしまうので冒頭であげたような問題が発生してしまう、というわけです。

だから

commonmark:
  options: ["UNSAFE", "SMART", "FOOTNOTES"]
  extensions: ["strikethrough", "autolink", "table", "tagfilter"]

のように UNSAFEtagfilter が両方指定されているのはどういう意味があるのか謎なんですよね。まあもちろん UNSAFE がないとそもそも iframe タグすら表示されないので挙動の違いはあるのですが、iframe をページに反映させると同時に HTML タグとしてそのまま表示させる、そんな需要あるのか?という疑問が浮かびました。

デザート

まあ単にぼくがあまり理解せずにそのままコピペしていたのが問題なんですが、意外に調べてもこのことを解説しているサイトは見つからなかったので備忘録として書くことにしました[1]

今回この問題をややこしくした(解決までに時間がかかった)のは、github-pages だとこの問題が発生しないからです。

gem 'github-pages'

ただこれ、考えてみれば当たり前で、github-pagesDependency versions に示されたライブラリやプラグインをもとに動作するように設計されていて、この中に Commonmarker は含まれていないんですよね。

つまり、github-pages を使った場合はこの設定は単に無視されて、代わりに kramdown が使われていたので冒頭のような問題が発生しなかった、ということになります。Jekyll は GitHub Pages のエコシステムと密につながっていて、このへんがちょっとわかりづらいと感じるのはぼくだけですかね 🤔

以上となります。わかっている人にとってはすごく当たり前のことを書きましたが、意外にハマってしまったので記録として残しておくことにしました。参考になれば幸いです。

脚注
  1. ChatGPT に聞いても意外とドンピシャな答えは返してくれませんでした。結果的には ChatGPT が提示した最小構成のサンプルを試したときに動いたのでその差分で原因にたどり着くことができたので壁打ちにはなりましたが。Jekyll ページネーション問題 ↩︎

GitHubで編集を提案

Discussion