搜索Ctrl+K
博客
MDX 実践:ブログ記事にポケモン図鑑を詰め込む

MDX 実践:ブログ記事にポケモン図鑑を詰め込む

· 更新于 | 3 分钟阅读

MDX 実践:ブログ記事にポケモン図鑑を詰め込む

ある日、ブログ記事の中にインタラクティブなポケモン図鑑を置きたくなった。

普通の人なら思うはずだ:それは無理だ、Markdown はただのプレーンテキストだと。

そして私は MDX を発見した。

MDX とは何か

MDX = Markdown + JSX。

簡単に言えば、.mdx ファイルの中に React コンポーネントを直接書けるということだ:

# これは普通の記事
本文の内容...
<MyComponent client:load />
続きを書く...

あとは Astro がやってくれる。Markdown を HTML にレンダリングし、React コンポーネントをインタラクティブな island として hydrate する。

実際に見てみよう

図鑑コンポーネントを書いて、ここで呼び出した:

import Pokedex from '../../../components/Pokedex';
<Pokedex client:load />

たったこの2行。そして少しだけ手を加えると——

Pokédex

中国語・英語・日本語・スペイン語での検索、18タイプのフィルター、デバウンスクエリ、ページネーション対応。

(「少しだけ」)

client:load の意味

Astro はデフォルトでクライアントサイド JS を一切実行しない。React コンポーネントを本当に動かすには、hydration ディレクティブが必要だ:

ディレクティブタイミング適した用途
client:loadページ読み込み時すぐすぐ操作が必要なもの(図鑑など)
client:idleブラウザがアイドル時優先度の低いウィジェット
client:visibleスクロールで見えた時ページ下部のコンポーネント
client:only="react"クライアントのみ、SSR スキップブラウザ API が必要なもの

図鑑はページ読み込みと同時にデータ取得を始める必要があるので、client:load を選んだ。

import パスの落とし穴

MDX 内の import は相対パスを使わなければならない — パスエイリアスは使えない:

✅ import Pokedex from '../../../components/Pokedex';
❌ import Pokedex from '@/components/Pokedex';

Astro はビルド時に MDX を解析するため、その段階ではエイリアスが利用できない場合がある。../ を数個余分に打つだけの話で、使えないわけではない。

まとめ

MDX を一言で:Markdown の中に React を書き、React の中に Markdown を書く

図鑑の PokeAPI GraphQL 呼び出し、多言語マッピング、デバウンス検索……あれらは全部「少しだけの手直し」なので重要ではない。

重要なのは、今私のブログ記事にポケモン図鑑があるということだ。

それだけが本当に重要なことだ。

© 2026 Leo Ji — Built with Astro