next-mdx-remote で Markdown の表が崩れる——GFM は remark-gfm を入れないと効かない
next-mdx-remote で MDX を描画しているサイトで、Markdownの表を書いたのに | 記号の生テキストがそのまま出て表にならない。表・取り消し線・タスクリストはCommonMark標準には無いGFM拡張なので、remark-gfmを入れないと素通りする。渡し方と、表の見た目はCSSで別途当てる点まで。
Markdown で表を書いたのに、記事に | 見出し | 見出し | の生テキストがそのまま出て、表にならない。next-mdx-remote で MDX(Markdown に部品を混ぜられる形式)を描画しているサイトでよく踏む。原因と直し方をまとめる。
事象
| a | b | と |---|---| で表を書くと、HTMLの表にならず、書いたパイプ記号がそのまま画面に出る。
原因
Markdown の「表」記法は、CommonMark(Markdown の標準仕様)には無い。GitHub が独自に足した拡張=GFM(GitHub Flavored Markdown)の機能だ。next-mdx-remote は内部で MDX のコンパイラ(remark)を使うが、そのデフォルトは CommonMark 準拠で、GFM 拡張を積んでいない。だから GFM の表記法は「ただのテキスト」として素通りする。
同じ理由で、取り消し線(~~)・タスクリスト(- [ ])・裸のURLの自動リンク化(https://… をそのまま書いてリンクにする)も効かない。これらもGFM拡張だ。ちなみに山カッコで囲む <https://…> 形式の自動リンクは CommonMark にあるので、そちらは remark-gfm 無しでも効く。
解決策
remark-gfm というプラグインを MDX の処理に渡す。
import { MDXRemote } from "next-mdx-remote/rsc";
import remarkGfm from "remark-gfm";
<MDXRemote
source={content}
options={{ mdxOptions: { remarkPlugins: [remarkGfm] } }}
/>
これで表・取り消し線・タスクリスト・脚注などが効くようになる。App Router(next-mdx-remote/rsc)ならこの形だ。Pages Router で serialize() を使う場合も、渡す先は同じ mdxOptions.remarkPlugins。
ひとつ注意。プラグインを足しても、表に枠線もセルの余白も付かない。素の <table> が出るだけなので、CSS(.prose table 等)で見た目を当てる必要がある。
見分け方
「パイプで書いた表が生テキストで出る」「~~取り消し線~~ が消えない」なら、GFM が効いていない。remark-gfm を入れる。