mdx-shiki-code-rendering
**MDX 技術記事のコードブロックを「VS Code 同等の精度で / dark mode 対応で / ファイル名タブ付きで / diff が一目で / 行ハイライト付き」で見せたい** 時に呼び出すべき skill。Shiki(VS Code と同じ TextMate grammar ベースのシンタックスハイライタ)の dual テーマ機能(light/dark を 1 回 build で両対応、CSS 変数で切替)、`title="file.ts"` でファイル名タブ、`{1,3-5}` 行ハイライト、` ```diff ` で `+` / `-` カラー、言語ヒント / inline code、Astro / Next.js / Docusaurus 等での組み込み設定。次のいずれかに該当する時に invoke する: (1) `astro.config.mjs` / `next.config.js` の `shikiConfig` を編集中、(2) MDX に大量のコードブロックを書く / それを綺麗に見せたい、(3) dark mode 対応のコード表示、(4) diff や行強調の表示要件。検証: shiki@1.x、Astro 6.x、2026-05-09。
MDX × Shiki コードレンダリング skill
検証: shiki@1.x / Astro 6.x の Shiki 統合 / MDX v3 検証日: 2026-05-09 対象: MDX で技術記事を書きながらコードブロックを「読み手にやさしく」見せたい時の実装
技術記事の 半分はコードブロック。コードの見た目で記事の信頼度が変わる。 Shiki は VSCode と同じシンタックスハイライタで、TextMate grammar ベースで言語の精度が高い。
まず詰まる 3 点
shikiConfig.themesを入れ忘れて灰色の世界になる(デフォルトは指定なし)- MDX に渡る
remarkプラグインとmarkdown設定は別系統(Astro 6 ではmdx({ shikiConfig })を別途渡す) - ファイル名タブの記法は処理系で違う(
title="..."派 vs:filename派)
デュアルテーマ(light / dark 自動切替)
Astro 6 の MDX 統合での書き方:
import mdx from "@astrojs/mdx";
export default defineConfig({
integrations: [
mdx({
shikiConfig: {
themes: {
light: "github-light",
dark: "github-dark",
},
wrap: true, // 長い行を折り返す(横スクロールを抑える)
},
}),
],
markdown: {
shikiConfig: {
themes: { light: "github-light", dark: "github-dark" },
wrap: true,
},
},
});
Astro は <pre style="--shiki-light: #...; --shiki-dark: #..."> の形で 両テーマ分の color CSS 変数を埋め込む。CSS 側で prefers-color-scheme に応じて変数を切り替えれば自動でダークモード対応:
@media (prefers-color-scheme: dark) {
pre, code {
color-scheme: dark;
}
}
Shiki が出力する <pre style="--shiki-dark: ..."></pre> を Astro が darkmode 時に dark 変数で上書き表示する仕組み。class 切り替えで dark mode を制御するなら defaultColor: false + 自前 CSS で対応する。
ファイル名タブ
import { sql } from "./client";
export async function findUser(id: string) {
return sql`SELECT * FROM users WHERE id = ${id}`;
}
上の例は title="src/lib/db.ts" を info string(言語の後ろのスペースの後)に書いた形。Astro / Next.js / Docusaurus いずれもこの記法を概ねサポート。
別記法に js:filename.js 形式(コロン区切り)もあるが、MDX v3 ベースのサイトでは title="..." のほうが portable。
行ハイライト
特定の行を強調する記法(rehype プラグインに依存):
import express from "express";
const app = express();
app.use((req, res, next) => { // ← highlight (3-5)
console.log(req.url);
next();
});
app.get("/", (req, res) => res.send("ok"));
app.listen(3000); // ← highlight (8)
Astro 標準の MDX には行ハイライト記法は組み込まれていない(rehype プラグインが必要)。
rehype-pretty-code か expressive-code をインストールするのが現実的。expressive-code は Astro 用の専用 integration があり、ファイル名タブ + 行ハイライト + 差分を統合的に扱える。
diff 表示
- const result = await fetch(url);
+ const result = await fetch(url, { signal: controller.signal });
``` の後ろに diff を指定 すると、+ / - の行が緑 / 赤で着色される。
複数言語を組み合わせたい場合は diff-ts のような派生 grammar を使う(処理系依存)。
inline code(ハイライト付き)
Shiki は inline code もハイライトできる:
インラインで {`const x: number = 1`} のように `const x: number = 1` と書ける。
Astro の <Code> コンポーネントを使えば確実:
---
import { Code } from "astro:components";
---
<Code code="const x: number = 1" lang="ts" inline />
inline code を多用する記事(API リファレンス系)では、専用 component を 1 つ作っておくと一貫性が出る。
言語ヒント(対応言語の指定)
Shiki は VSCode 互換の grammar を内蔵。よく使う言語:
| 言語 | 指定子 |
|---|---|
| TypeScript | ts, typescript |
| JSX/TSX | tsx, jsx |
| JSON | json, jsonc(コメント付き) |
| Shell | sh, bash, zsh |
| 環境ファイル | dotenv |
| 設定ファイル | toml, yaml, ini |
| 図記法 | mermaid(レンダリング処理は別途必要) |
txt か text でハイライト無し。出力例 / ログ表示に向く。
よく詰まる落とし穴
mdx({ shikiConfig })とmarkdown.shikiConfigを両方設定しないと、.mdと.mdxで見た目が違う — どちらにも同じ shikiConfig を渡す- CSS 変数の prefix を変えると Astro 標準のダークモード切替が壊れる —
--shiki-prefix は変えない - 大きいコードブロックで build が遅くなる — Shiki は build 時にレンダリングするので、巨大ファイル(数千行)を貼ると build が重くなる。抜粋 + 「全文は 」 に分割
- 言語指定子が間違うと無音で fallback する —
jsとjavascriptは OK、javascは灰色になる(エラーにならない) - VSCode のシンタックスハイライトと若干違う — VSCode は別 grammar を併用していることがある
推奨セットアップ(Astro 6 MDX サイト)
import { defineConfig } from "astro/config";
import mdx from "@astrojs/mdx";
const shikiConfig = {
themes: { light: "github-light", dark: "github-dark" },
wrap: true,
};
export default defineConfig({
integrations: [
mdx({
shikiConfig,
// 行ハイライト / 差分が欲しいなら expressive-code 等を別途追加
}),
],
markdown: { shikiConfig },
});
expressive-code を使う場合は astro-expressive-code integration を追加して mdx() を後にする(Astro 公式のドキュメントに従う)。
向く / 向かないケース
- 向く: MDX/MD ベースの技術記事、ドキュメントサイト、ブログ、書籍
- 向かない: ランタイムで生成されるコード(LLM 出力等)→ shiki/wasm を browser ロードする選択肢あり、ただし bundle サイズに注意
- 向かない: 非常に大きなコードブロック(数千行)→ link or embed gist を検討
See also(任意、単独でも完結)
本 skill は MDX × Shiki に特化しており、単独で完結します。記事化する場合は本リポの src/content/methodology/01-editorial-principles を参照。
参考
- Shiki: https://shiki.style
- Astro Markdown 設定: https://docs.astro.build/en/guides/markdown-content/
- expressive-code: https://expressive-code.com