言語を切り替える
テーマを切り替える

Astro Markdown活用ガイド:ブログをプロ仕様に格上げする7つの高等テクニック

Astroでブログを立ち上げ、いざ技術記事を書き始めたとき、ふと物足りなさを感じることはありませんか?
「コードのこの行だけハイライトしたいのに…」「注意事項を目立つアラートボックスで表示したい」「アルゴリズムの解説に数式を入れたいけど書き方がわからない」

私も同じ悩みを抱えていました。純粋なMarkdownだけでは、表現力に限界があるのです。世の中の洗練された技術ブログを見ると、コードブロックに差分が表示されていたり、記事の中にリッチなUIパーツが埋め込まれていたりと、羨ましくなることばかり。かたや自分は、ただ淡々とコードを貼り付けるだけ。

しかし、Astroには MDX という強力な武器があります。MDXを使えば、記事の中でコンポーネントを使ったり、JSXを書いたりと、できることが一気に広がります。

この記事では、AstroのMarkdown/MDX機能を使い倒すための7つの高度なテクニックを紹介します。環境構築の基礎から、コードハイライトのカスタマイズ、独自コンポーネントの実装、数式や図表の統合まで、すべての手順をコード付きで解説します。これを読めば、あなたのブログは「ただ読める」ものから「プロフェッショナルな」ものへと進化するはずです。

第1部:基本編 - Markdown から MDX へ

なぜ MDX なのか?

MarkdownとMDXの違いは、自転車と電動アシスト自転車の違いのようなものです。どちらも走れますが、できることの範囲と体験が全く異なります。

純粋なMarkdownは、テキスト、コードブロック、画像といった静的なコンテンツしか扱えません。アラートボックスを表示したければ、HTMLを直接書くしかありません。インタラクティブなコンポーネントを埋め込むなんて夢のまた夢です。

一方、MDXは「Markdown + JSX」のハイブリッドです。以下のことが可能になります:

  • コンポーネントの使用: .mdx ファイル内で、AstroコンポーネントやReact/Vueコンポーネントを直接 import して使用できます。
  • JSX式の記述: {variable} のように変数を挿入したり、ループや条件分岐を書いたりできます。
  • 要素のカスタマイズ: 標準の <h1> タグなどを、自作のスタイリッシュなコンポーネントに置き換えることができます。

具体例を見てみましょう。記事に警告ボックスを表示したい場合、純粋なMarkdownならHTMLを書く必要があります:

<div class="warning">
  <p>注意:この操作はすべてのデータを削除します!</p>
</div>

MDXなら、もっと直感的です:

import Alert from '@/components/Alert.astro';

<Alert type="warning">
  注意:この操作はすべてのデータを削除します!
</Alert>

ご覧の通り、MDXを使えば記事作成が「コーディング」ではなく「積み木遊び」のように直感的になります。

5分でできる MDX 環境構築

MDXのセットアップは驚くほど簡単です。たった3ステップです。

ステップ1:統合パッケージのインストール

ターミナルでAstroプロジェクトのルートディレクトリを開き、以下を実行します:

npx astro add mdx

Astro CLIが自動的に @astrojs/mdx をインストールし、設定ファイルを更新してくれます。質問(設定を更新しますか?など)にはすべて Yes で答えてください。

ステップ2:設定の確認

astro.config.mjs を開き、以下のようになっているか確認します:

import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';

export default defineConfig({
  integrations: [mdx()],
});

もし自動追加されていなければ、手動で記述してください。

ステップ3:動作確認

src/pages/ または src/content/ 下に test.mdx ファイルを作成してみましょう:

---
title: MDXテスト
---

# これはMDXのテストです

普通のMarkdownテキスト。

export const greeting = "こんにちは";

変数も使えます:{greeting}

<div style="padding: 1rem; background: #f0f0f0;">
  これはJSX要素です
</div>

npm run dev で起動し、ページにアクセスして変数やスタイルが表示されていれば成功です。

補足:.md と .mdx の共存

MDXを導入しても、既存の .md ファイルはそのまま使えます。Astroは拡張子を見て処理方法を切り替えます:

  • .md: 標準Markdownとして処理
  • .mdx: MDXとして処理(コンポーネントやJSX対応)

通常の記事は .md で、コンポーネントを使いたい記事だけ .mdx にする、といった使い分けも可能です。

第2部:コードハイライトの実践テクニック

テーマのカスタマイズ(Shiki)

Astroはデフォルトで Shiki というハイライターを使用しています。標準の github-dark も悪くないですが、ブログの雰囲気に合わせてテーマを変えたいこともありますよね。

Shiki か Prism か?

私は断然 Shiki をおすすめします。Astro標準であり、追加のJSロードなしでハイライトされ、100以上の言語に対応しています。Prismも良いですが、設定が少し複雑です。

テーマの変更

astro.config.mjsmarkdown オプションに shikiConfig を追加します:

export default defineConfig({
  integrations: [mdx()],
  markdown: {
    shikiConfig: {
      theme: 'dracula', // github-dark, nord, monokai, dracula など
    },
  },
});

利用可能なテーマは Shiki Theme Preview で確認できます。

ライト/ダークモード対応

ダークモード切り替えに対応させたい場合は、デュアルテーマを設定できます:

markdown: {
  shikiConfig: {
    themes: {
      light: 'github-light',
      dark: 'github-dark',
    },
  },
},

これで、CSS変数やメディアクエリに応じてテーマが自動的に切り替わるようになります。

特定行のハイライトとコメント装飾

チュートリアル記事を書くとき、「ここが重要!」と行を強調したり、「ここを変更しました」と差分を見せたりしたいですよね。Shiki Transformers を使えば簡単です。

ハイライト機能の有効化

まずパッケージをインストールします:

npm install shiki

設定ファイルで transformerNotationHighlight を有効化します:

import { transformerNotationHighlight } from '@shikijs/transformers';

export default defineConfig({
  markdown: {
    shikiConfig: {
      transformers: [transformerNotationHighlight()],
    },
  },
});

これで、コードブロック内のコメントで // [!code highlight] と書けば、その行がハイライトされます:

```javascript
function hello() {
  console.log('普通の行');
  console.log('ここがハイライトされます'); // [!code highlight]
}
```

差分表示(Diffスタイル)

変更前後の比較には transformerNotationDiff が便利です:

import { transformerNotationDiff } from '@shikijs/transformers';
// transformers 配列に追加してください

使い方は // [!code --]// [!code ++] を行末に追加するだけです:

```javascript
function calculate(a, b) {
  return a + b; // [!code --]
  return a * b; // [!code ++]
}
```

フォーカス表示

transformerNotationFocus を使うと、指定行以外をグレーアウトして目立たせることができます。

Expressive Code へのアップグレード(おすすめ)

Shikiの設定が面倒だ、もっとリッチな機能(コピーボタンやファイル名表示など)が欲しい、という場合は Expressive Code を導入しましょう。

インストールは一発です:

npx astro add astro-expressive-code

これを入れるだけで、コードブロックに以下の機能が追加されます:

  • ファイル名のタイルト表示
  • コピーボタン
  • 行番号
  • ターミナル風ウィンドウ
  • 差分表示の簡略化

技術ブログをガッツリ書くなら、デフォルトのShikiよりExpressive Codeの方が満足度は高いでしょう。

第3部:カスタムコンポーネントの活用

MDXでのコンポーネント利用

MDXの真骨頂、コンポーネントの埋め込みです。アラート、コード比較、折りたたみなど、自由にUIを作って記事内で使えます。

アラートコンポーネントを作る

src/components/Alert.astro:

---
interface Props {
  type?: 'info' | 'warning' | 'error';
}
const { type = 'info' } = Astro.props;
const styles = {
  info: 'bg-blue-50 border-blue-200 text-blue-800',
  warning: 'bg-yellow-50 border-yellow-200 text-yellow-800',
  error: 'bg-red-50 border-red-200 text-red-800',
};
---
<div class={`border-l-4 p-4 ${styles[type]}`}>
  <slot />
</div>

記事での使用

import Alert from '@/components/Alert.astro';

# 記事タイトル

<Alert type="warning">
  注意:バックアップを取ってから実行してください!
</Alert>

コンポーネント内(<Alert>...</Alert> の間)でもMarkdown記法が使えるのがMDXの素晴らしいところです。

React/Vueコンポーネントの使用

もちろんReactなどのコンポーネントも使えます。その際は client: 指令を忘れずに:

import Counter from '@/components/Counter.tsx';

<Counter client:load initialCount={0} />

client:load がないと、インタラクションのないただの静的HTMLとしてレンダリングされてしまいます。

Markdown要素のマッピング(上級編)

「記事内のすべてのリンクに、外部リンクならアイコンを付けたい」「見出しには自動でアンカーリンクを付けたい」
そんな時は、標準のHTML要素を自作コンポーネントに置き換える(マッピングする)機能を使います。

カスタムリンクコンポーネント

src/components/ExternalLink.astro:

---
interface Props { href?: string; }
const { href } = Astro.props;
const isExternal = href?.startsWith('http');
---
<a href={href} target={isExternal ? '_blank' : undefined} 
   rel={isExternal ? 'noopener noreferrer' : undefined}>
  <slot />
  {isExternal && <span class="ml-1 text-xs">↗</span>}
</a>

MDXでのマッピング

記事ファイル内で components オブジェクトをエクスポートします:

import ExternalLink from '@/components/ExternalLink.astro';

export const components = {
  a: ExternalLink,
};

[内部リンク](/about)
[外部リンク](https://example.com) ← 自動でアイコンがつきます

これで、いちいちコンポーネントタグを書かなくても、普通のMarkdownリンク記法を書くだけでリッチな表示になります。

第4部:数式と図表の統合

KaTeX による数式表示

アルゴリズムや統計の記事には数式が不可欠です。Astroでは KaTeX を使うのが一般的です。

インストール

npm install remark-math rehype-katex katex

設定

astro.config.mjs:

import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';

export default defineConfig({
  integrations: [mdx()],
  markdown: {
    remarkPlugins: [remarkMath],
    rehypePlugins: [rehypeKatex],
  },
});

CSSの読み込み

数式を正しく表示するにはスタイルシートが必要です。レイアウトファイルの <head> に追加してください:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css" crossorigin="anonymous" />

使い方

Markdown内でLaTeX記法が使えます。
インライン:$E = mc^2$
ブロック:

\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}

Mermaid によるフローチャート

技術解説にはフローチャートやシーケンス図が便利です。Mermaid を統合しましょう。

おすすめは rehype-mermaid です。ビルド時にSVG画像を生成してくれるため、SEOに強く、読み込みも高速です。

インストール

npm install rehype-mermaid

設定

import rehypeMermaid from 'rehype-mermaid';

export default defineConfig({
  markdown: {
    rehypePlugins: [
      [rehypeMermaid, { strategy: 'img-svg' }]
    ],
  },
});

使い方

コードブロックの言語に mermaid を指定するだけです:

```mermaid
graph TD
    A[開始] --> B{MDX導入済み?}
    B -->|Yes| C[記事を書く]
    B -->|No| D[npm install]
    D --> C
```

第5部:高度なテクニックとベストプラクティス

Content Collections との連携

ブログ運営には Content Collections が強く推奨されます。MDXのフロントマター(記事メタデータ)を型安全に扱えるようになります。

src/content/config.ts:

import { defineCollection, z } from 'astro:content';

const blog = defineCollection({
  type: 'content',
  schema: z.object({
    title: z.string(),
    tags: z.array(z.string()).optional(),
  }),
});
export const collections = { blog };

これでフロントマターの記述ミス(必須項目の欠落など)をビルド時に検知できます。
また、MDX記事内でもフロントマターの値を利用できます:

---
title: テスト記事
---

# {frontmatter.title}

パフォーマンスの落とし穴

MDXは便利ですが、使いすぎるとパフォーマンスを損ないます。

注意点:クライアントコンポーネントの乱用
Reactコンポーネントなどに client:load を付けまくると、JSのバンドルサイズが肥大化します。
「動き」が必要ないなら、極力Astroコンポーネント(サーバーサイドレンダリングのみ)を使いましょう。
インタラクションが必要な場合も、client:visible(表示されたらロード)や client:idle(アイドル時にロード)を検討してください。

画像最適化
MDX内でも <img> タグの代わりにAstroの <Image /> コンポーネントを使いましょう。

import { Image } from 'astro:assets';
import cover from './cover.jpg';

<Image src={cover} alt="表紙" width={800} />

これで画像の最適化(WebP変換、遅延ロード)が自動適用されます。

まとめ

長くなりましたが、重要ポイントを振り返ります:

  1. MDX導入: npx astro add mdx で5分セットアップ。
  2. コードハイライト: Shiki や Expressive Code で見やすく。
  3. コンポーネント活用: Alertなどで表現力アップ。
  4. 数式・図表: KaTeX, Mermaid で技術解説をリッチに。

これらをすべて最初からやる必要はありません。まずは環境を整えて、簡単なコンポーネントを1つ使ってみることから始めてみてください。
MDXを使いこなせば、技術ブログの表現力は「メモ書き」レベルから「技術書」レベルへと飛躍的に向上します。ぜひあなたのブログでも試してみてください!

Astro Markdown/MDX 高度設定ガイド

ブログの表現力を高めるためのMDX、コードハイライト、数式、図表の設定完全フロー

⏱️ Estimated time: 1 hr

  1. 1

    Step1: MDXの導入

    npm install @astrojs/mdx でパッケージを追加し、astro.config.mjs の integrations に追加。これで.mdxファイルがコンパイル可能になります。
  2. 2

    Step2: コードハイライトの設定

    Shikiのテーマを config で指定し、transformers を導入して行ハイライトやDiff表示を有効化します。
  3. 3

    Step3: カスタムコンポーネントの実装

    Alert.astro などのUIコンポーネントを作成し、MDXファイル内で import して使用。Markdown要素のマッピングも検討します。
  4. 4

    Step4: 数式と図表の統合

    remark-math / rehype-katex で数式を、rehype-mermaid でフローチャートを表示できるようにプラグインを設定します。

FAQ

MDXとMarkdownの違いは何ですか?
MDXはMarkdownにJSX(JavaScript XML)の機能を拡張したものです。Markdownの書きやすさはそのままに、ReactやAstroコンポーネントを埋め込んだり、変数を展開したり、式を評価したりできます。
数式が表示されません
KaTeXのプラグイン導入だけでなく、CSSの読み込みが必要です。ヘッダー(<head>タグ内)に katex.min.css へのリンクが貼られているか確認してください。
ビルドが遅くなりました
MDXファイルが大量にある場合、ビルド時間が増加することがあります。astro.config.mjs の mdx 設定で { optimize: true } を試してみてください。これは実験的な機能ですが、パフォーマンスを改善する場合があります。

4 min read · 公開日: 2025年12月2日 · 更新日: 2026年1月22日

コメント

GitHubアカウントでログインしてコメントできます

関連記事