
記事を公開してから気づきました。
Obsidian でコードブロックを書いているときは、言語ごとに色がついて見やすく表示されています。 バッチファイルを実行して next ブログに公開した後、公開した記事を開いてみると、コードブロックが全部同じ色のプレーンテキストになっていました。
コピーボタンもありません。
公開するまで気づかなかった理由はシンプルで、記事を書いているのが Obsidian だからです。 Obsidian のプレビューでは当然きれいに表示されるので、問題があるとは思っていませんでした。

原因はすぐわかった
react-markdown はデフォルトでシンタックスハイライト(コードの色付け)機能を持っていません。
Obsidian には標準で組み込まれているので意識したことがありませんでしたが、 react-markdown はコードブロックをただの <code> タグとして出力するだけです。言語を指定しても色はつきません。
解決策も調べればすぐ出てきました。 react-syntax-highlighter というライブラリを使えばよいとわかりました。
実装でハマったこと
解決策がわかったので、コードを書いて page.tsx に追加してビルドしたところ、エラーになりました。
Error: Event handlers cannot be passed to Client Component props.
{onClick: function onClick, ...}
コピーボタンに onClick を使っているのですが、 page.tsx はサーバーコンポーネントのため onClick が使えない、というエラーです。
「サーバーコンポーネント」と「クライアントコンポーネント」の違いは知識としては知っていましたが、実際にエラーになって初めて「あ、ここで引っかかるのか」と実感しました。
対処は 'use client' を先頭に書いた別ファイルに分離することです。
tsx'use client'; // この1行があるとクライアントコンポーネントになる // onClick のようなブラウザ上のインタラクションが使えるようになる
page.tsx 全体を 'use client' にするとサーバーサイドレンダリングの恩恵が失われるので、コードブロック部分だけ components/CodeBlock.tsx という別ファイルに切り出してそちらだけクライアントコンポーネントにする設計にしました。
分離してビルドしたら通りました。
完成した見た目

コードブロックの左上に言語名、右上にコピーボタンが表示されるようになりました。カラーテーマは oneDark を使っています。ダークテーマのブログに馴染んでいて良い感じです。
気づいたこと
今回は「公開してから問題に気づいた」という順序になりましたが、こういうことは開発環境と本番環境の見た目が違う以上、ある程度避けられないと思います。
ローカルで開発しているわけではなく Obsidian で書いているので、余計に「ブログでどう見えるか」を意識しにくい構造になっています。
今後も公開後に気づく問題は出てくると思うので、その都度直していけばいい、という気持ちで進めています。
メインブログでは実装の手順を詳しく解説しています。





