Next.js と Markdown を使ったブログ構成では、URL が表示されているのにクリックできないというトラブルに遭遇することがあります。
一見すると CSS の問題に見えるため、原因の切り分けでハマりやすいのが特徴です。
本記事では、実際に発生した事例をもとに、
- なぜリンクがクリックできなかったのか
- CSS では直らない理由
- 運用を続けやすい正しい解決方法
を順序立てて整理します。
単なる対処ではなく、長期運用を前提とした構成の考え方まで落とし込むことを目的としています。
この記事で分かること
- リンクがクリックできない本当の原因
- CSS では直らないケースの見分け方
- remark-gfm を使った正しい解決方法
- 同じ問題を繰り返さないための確認ポイント
先に結論
下記記事を運用していくときに気づいた点です。

リンクがクリックできなかった原因は CSS ではありません。
問題は、
Markdown → HTML 変換の段階で <a> タグが生成されていなかったことでした。
画面上に URL が表示されていても、HTML 上で <a href="..."> が存在しなければ、ブラウザはリンクとして扱いません。
この点を見落とすと、CSS をいくら調整しても状況は変わらないままになります。
実際に起きていた状態
このブログでは、Markdown 内に次のように URL をそのまま記述していました。
<https://blog.jetbrains.com/dotnet/2026/01/05/dotinsights-january-2026/>
表示上は問題なく URL が出力されます。
しかし、Chrome の開発者ツールで生成後の HTML を確認すると、次のような状態でした。
<p>
<https://blog.jetbrains.com/dotnet/2026/01/05/dotinsights-january-2026/>
</p>
この HTML には <a> タグが存在しません。
つまり、クリックできないのは仕様どおりの挙動です。
なぜ <a> タグにならなかったのか
今回の構成では、Markdown を HTML に変換するために次のライブラリを使用していました。
- remark
- remark-html
この組み合わせには、プレーンな URL を自動的にリンクへ変換する機能が含まれていません。
GitHub や Qiita では URL を書くだけでリンク化されるため、
「Markdown なら当然リンクになる」と思い込みやすい点が落とし穴です。
Next.js で Markdown 処理を自前実装している場合、
どこまでを拡張仕様として有効にしているかを明示的に管理する必要があります。
正しい解決方法:remark-gfm を使う
対応方針の整理
今回の問題を踏まえ、次の方針で解決策を選びました。
- Markdown はできるだけシンプルに書きたい
- 記事作成者がリンク記法を毎回意識しない構成にしたい
- 記事数が増えても運用が破綻しない形にしたい
これらを満たす解決策が remark-gfm の導入です。
remark-gfm を使うメリット
- プレーンな URL を自動でリンク化できる
- GitHub と同じ Markdown 拡張仕様に対応
- 表、チェックボックス、打ち消し線などにも将来的に対応可能
結果として、
「URL を貼るだけでリンクになる」環境を構築できます。
実装例(Next.js + remark)
Next.js(Node.js)で Markdown を HTML に変換する例
import { remark }from"remark";
import htmlfrom"remark-html";
import remarkGfmfrom"remark-gfm";
exportasyncfunctionmarkdownToHtml(markdown:string) {
const result =awaitremark()
.use(remarkGfm)
.use(html)
.process(markdown);
return result.toString();
}
この設定を入れるだけで、Markdown 内に次のように書いた URL が、
<https://example.com>
HTML では次の形に変換されます。
<a href="<https://example.com>"><https://example.com></a>
これにより、
- 確実にクリックできる
- CSS での装飾が正しく適用される
- 記事作成時の負担が減る
という状態になります。
CSSでハマりやすい誤解
リンクがクリックできないと、次のような CSS 周りを疑いがちです。
pointer-eventsの指定- 疑似要素がリンクを覆っている
z-indexの重なり問題
ただし、そもそも <a> タグが存在しない場合、CSS では絶対に解決しません。
まず最初にやるべきことは、
- 開発者ツールで
<a>タグが生成されているか確認する
これだけです。
HTML 構造が正しくなければ、CSS は意味を持ちません。
運用視点でのベストプラクティス
今回の対応から得られた、運用上の重要なポイントは次の3点です。
- Markdown は「内容」に集中する
- 見た目は CSS で一括管理する
- 構文解釈は変換レイヤーに任せる
この責務分離を守ることで、
- 記事数が増えても修正箇所が限定される
- デザイン変更が容易になる
- 書き手の負担が増えない
といったメリットがあります。
CSS調整で一度ハマったポイント(補足)
今回のトラブルでは、最初に CSS が原因ではないか と考え、いくつかの調整も行いました。
これは結果的に遠回りでしたが、切り分けとしては正しいプロセスでもあります。
実際に行った CSS 調整
- Tailwind Typography(
@tailwindcss/typography)の導入 .proseクラスによる行間・段落余白の調整- 見出し(h2)の太字化や装飾
- 外部リンクに 🔗 アイコンを付ける疑似要素の追加
これらは 可読性向上という意味では有効な改善でした。
なぜ CSS では直らなかったのか
理由は明確です。
- HTML に
<a>タグが存在していなかった - クリック対象そのものが生成されていなかった
CSS は「存在する要素」を装飾するものであり、
存在しない要素を機能させることはできません。
CSS調整は無意味だったのか?
結論としては 無意味ではありません。
- 行間や余白が整い、読みやすくなった
- 見出し構造が視覚的に分かりやすくなった
- リンクがリンクとして認識しやすくなった
つまり、
- 構造の問題(HTML生成)
- 見た目の問題(CSS)
を分離して考えられた、という点で価値のある工程でした。
まとめ
- リンクがクリックできない原因は CSS ではなかった
- Markdown → HTML 変換時に
<a>タグが生成されていなかった - remark-gfm を使うことでプレーン URL を自動リンク化できる
- CSS 調整は可読性向上としては有効だった
- 問題切り分けでは「HTML 構造の確認」が最優先
Next.js + Markdown でブログを運用する場合は、
- 構造(変換)
- 見た目(CSS)
を分離して考えることが、
長く安定して運用するための重要なポイントになります。

コメント