nisshi.devブログで使えるMDX記法紹介

nisshi.devブログで使えるMDX記法紹介

このページは実装したソースコードを元に Claude Code Agent Skills(Claude Opus 4.6)で自動生成し、著者(nisshi-dev)がレビュー・修正して公開しています。

このブログは、MDX記法で記事を書けるように環境構築しています。Fumadocsというドキュメントフレームワークをベースに、独自のremarkプラグインやReactコンポーネントを追加しており、3Dモデルなどのインタラクティブコンテンツも記事に直接埋め込めます。

このページでは、使える記法とコンポーネントをプレビュー付きで紹介します。自分のMDXブログで同様のことを実現したい方の参考になれば幸いです。

なお、UIコンポーネントカタログ(Storybook)は以下で公開しているので、興味があればご覧ください。

storybook.nisshi.dev

基本的なMarkdown構文

見出し

## 見出し2
### 見出し3
#### 見出し4

テキスト装飾

**太字テキスト**
*斜体テキスト*
~~取り消し線~~
`インラインコード`

太字テキスト斜体テキスト取り消し線インラインコード

リスト

- 箇条書き1
- 箇条書き2
  - ネストした項目

1. 番号付きリスト1
2. 番号付きリスト2
  • 箇条書き1
  • 箇条書き2
    • ネストした項目
  1. 番号付きリスト1
  2. 番号付きリスト2

引用

> これは引用文です。
> 複数行にまたがることもできます。

これは引用文です。 複数行にまたがることもできます。

リンク

外部リンクと内部リンクで表示が異なります。外部リンクには自動的にリンク先が外部サイトであることを示すマーク(↗)が付きます。

外部リンク

[Google](https://google.com)

Google

内部リンク

[ブログ一覧](/blog)

ブログ一覧


コードブロック

基本

```js
console.log('Hello World');
```
console.log('Hello World');

ファイル名付き

titleオプションでファイル名を表示できます。

```typescript title="src/components/Button.tsx"
export function Button({ onClick }: { onClick: () => void }) {
  return <button onClick={onClick}>Click me</button>;
}
```
src/components/Button.tsx
export function Button({ onClick }: { onClick: () => void }) {
  return <button onClick={onClick}>Click me</button>;
}

行番号

lineNumbersオプションで行番号を表示できます。開始行を指定することも可能です。

```js lineNumbers
function hello() {
  console.log("Hello");
}
```

```js lineNumbers=10
// 10行目から開始
function world() {
  console.log("World");
}
```
function hello() {
  console.log("Hello");
}
// 10行目から開始
function world() {
  console.log("World");
}

行ハイライト

Shikiトランスフォーマーを使用して特定の行をハイライトできます。

```js
const highlighted = true; 
const normal = true;
```
const highlighted = true; 
const normal = true;

差分表示

追加・削除行を視覚的に表示できます。

```js
console.log("Hello"); 
console.log("World"); 
```
console.log("Hello"); 
console.log("World"); 

シンタックスハイライト

main.py
def hello_world():
    print("Hello, World!")

hello_world()
Terminal
npm install my-package
package.json
{
  "name": "my-project",
  "version": "1.0.0"
}

パッケージインストール

npm/yarn/pnpm/bunの切り替えタブ付きで表示します。

```package-install
my-package
```
npm install fumadocs-ui

TypeScript ⇔ JavaScript 変換

ts2jsオプションで切り替え表示できます。

```tsx ts2js
import { ReactNode } from 'react';
export default function Layout({ children }: { children: ReactNode }) {
  return <div>{children}</div>;
}
```
import { ReactNode } from 'react';
export default function Layout({ children }: { children: ReactNode }) {
  return <div>{children}</div>;
}

タブ付きコードブロック

tabオプションで複数コードをタブ表示できます。

```ts tab="TypeScript"
const message: string = "Hello";
```

```js tab="JavaScript"
const message = "Hello";
```
const message: string = "Hello";

Callout(注意書き)

:::type構文で注意書きブロックを作成できます。

タイプ用途
info補足情報(デフォルト)
note / tipinfoのエイリアス
warning / warn警告・注意事項
dangerエラー・重要な警告
success成功・完了メッセージ

タイトル付き

:::type[タイトル]構文でカスタムタイトルを設定できます。

:::info[補足情報]
これはカスタムタイトル付きの補足情報です。
:::

:::info
これは補足情報です。
:::

:::warning
これは警告メッセージです。
:::

:::danger
これはエラーメッセージです。
:::

:::success
これは成功メッセージです。
:::

補足情報

これはカスタムタイトル付きの補足情報です。

これは補足情報です。

これは警告メッセージです。

これはエラーメッセージです。

これは成功メッセージです。


Cards(カードリンク)

関連ページへのリンクをカード形式で表示します。

<Cards>
  <Card title="Next.jsについて学ぶ" href="https://nextjs.org/docs" />
  <Card title="Fumadocsについて学ぶ" href="https://fumadocs.dev" />
</Cards>

説明付き

<Cards>
  <Card href="https://nextjs.org/docs" title="データフェッチング">
    Next.jsでのデータ取得方法について学びます
  </Card>
  <Card title="hrefは省略可能">
    リンクなしの説明カードも作れます
  </Card>
</Cards>

データフェッチング

Next.jsでのデータ取得方法について学びます

hrefは省略可能

リンクなしの説明カードも作れます


nisshi.dev独自実装

このコンポーネントはnisshi.devで独自に実装したものです。OGP情報を自動取得してリンクカードを表示します。

URLを単独行に書くと、自動的にOGP付きリンクカードになります。

https://nextjs.org

https://fumadocs.dev

https://github.com/honojs/hono
nextjs.org
fumadocs.dev
github.com

手動指定

LinkCardコンポーネントで手動指定も可能です。

Prop必須説明
urlstringリンク先URL
titlestring-タイトル(指定するとOGP取得をスキップ)
descriptionstring-説明文
imagestring-画像URL
<LinkCard
  url="https://example.com"
  title="サイトのタイトル"
  description="サイトの説明文"
/>

数式(KaTeX)

LaTeX記法で数式を書けます。

インライン

ピタゴラスの定理: $$c = \pm\sqrt{a^2 + b^2}$$

ピタゴラスの定理: c=±a2+b2c = \pm\sqrt{a^2 + b^2}

ブロック

```math
E = mc^2
```
E=mc2E = mc^2
```math
\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}
```
ex2dx=π\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}

メディア埋め込み

画像

nisshi.dev独自実装

画像はクリックで拡大表示できます。react-medium-image-zoomを採用しています。

github.com
![サンプル画像](https://pbs.twimg.com/media/G0Hwhu-bUAEbQBC?format=jpg&name=small)

Figure(キャプション付き画像)

nisshi.dev独自実装

このコンポーネントはnisshi.devで独自に実装したものです。

画像などにキャプションを付けるコンポーネントです。

Prop必須説明
captionReactNodeキャプション(説明文。文字列またはJSX)
childrenReactNode子要素(画像など)
classNamestring-カスタムクラス名
<Figure caption="イベント会場の様子">
  ![会場写真](./venue.jpg)
</Figure>

サンプル画像にキャプションを付けた例

Video(動画)

nisshi.dev独自実装

このコンポーネントはnisshi.devで独自に実装したものです。WebM形式の場合、自動的にMP4フォールバックを追加します。media-chromeを採用しています。

github.com

動画プレイヤーコンポーネントです。

Prop必須説明
srcstring動画のURL
fallbackSrcstring-フォールバック用動画URL
altstring-代替テキスト(アクセシビリティ用)
posterstring-ポスター画像URL
autoPlayboolean-自動再生(デフォルト: false)
loopboolean-ループ再生(デフォルト: false)
mutedboolean-ミュート(デフォルト: false)
childrenReactNode-キャプション
<Video src="/content/blog/example/video.webm" alt="デモ動画の再生画面">
  動画の説明テキスト
</Video>

iPad OS上でQuick Lookの3Dモデルを表示した様子

Model3D(3Dモデル)

nisshi.dev独自実装

このコンポーネントはnisshi.devで独自に実装したものです。@google/model-viewerを採用しています。AR機能(iOS Quick Look / Android Scene Viewer)に対応しています。

github.com

GLB/GLTF形式の3Dモデルを表示します。カメラ操作で回転・ズーム・パンが可能です。

Prop必須説明
srcstringモデルファイルのパス
altstring-モデルの説明(アクセシビリティ用)
childrenReactNode-キャプション
heightstring | number-ビューアーの高さ(デフォルト: "400px")
autoRotateboolean-自動回転(デフォルト: false)
autoRotateSpeednumber-自動回転速度(度/秒、デフォルト: 30)
arboolean-AR機能を有効化(デフォルト: true)
posterstring-ポスター画像のURL
iosSrcstring-iOS用のUSDZファイルパス
<Model3D src="/models/robot.glb" alt="ロボットモデル" autoRotate>
  3Dロボットモデル(ドラッグで回転、ホイールでズーム)
</Model3D>

宇宙服の3Dモデル(ドラッグで回転、ホイールでズーム)

VrmViewer(VRMアバター)

nisshi.dev独自実装

このコンポーネントはnisshi.devで独自に実装したものです。@pixiv/three-vrmとReact Three Fiberを採用しています。VRM 0.x/1.0両対応で、揺れもの(SpringBone)にも対応しています。

github.com

VRM形式の3Dアバターを表示します。OrbitControlsで回転・ズーム・パン操作が可能です。

Prop必須説明
srcstringVRMファイルのパス
altstring-モデルの説明(アクセシビリティ用)
childrenReactNode-キャプション
heightstring | number-ビューアーの高さ(デフォルト: "350px")
autoRotateboolean-自動回転(デフォルト: false)
autoRotateSpeednumber-自動回転の速度(デフォルト: 1.0)
scalenumber-モデルのスケール(デフォルト: 1)
cameraPosition[number, number, number]-カメラの初期位置(デフォルト: [0, 1.5, 3])
debugboolean-デバッグ情報を表示(デフォルト: false)
<VrmViewer src="/models/avatar.vrm" alt="VRMアバター">
  VRMアバター(ドラッグで回転、ホイールでズーム)
</VrmViewer>

VRMアバター(ドラッグで回転、ホイールでズーム)

SplatViewer(3D Gaussian Splat)

nisshi.dev独自実装

このコンポーネントはnisshi.devで独自に実装したものです。@sparkjsdev/sparkとReact Three Fiberを採用しています。

github.com

3D Gaussian Splatting形式のシーンを表示します。.ply, .spz, .splat, .ksplat, .sog形式に対応しています。

Prop必須説明
srcstringSplatファイルのパス
altstring-モデルの説明(アクセシビリティ用)
childrenReactNode-キャプション
heightstring | number-ビューアーの高さ(デフォルト: "350px")
autoRotateboolean-自動回転(デフォルト: false)
autoRotateSpeednumber-自動回転の速度(デフォルト: 1.0)
scalenumber-モデルのスケール(デフォルト: 1)
cameraPosition[number, number, number]-カメラの初期位置(デフォルト: [0, 0, 5])
debugboolean-デバッグ情報を表示(デフォルト: false)
<SplatViewer src="/splats/scene.spz" alt="3Dスキャンシーン">
  Gaussian Splatシーン(ドラッグで回転、ホイールでズーム)
</SplatViewer>

Gaussian Splattingで撮影したワークショップ風景

TilesViewer(3D Tiles)

nisshi.dev独自実装

このコンポーネントはnisshi.devで独自に実装したものです。3d-tiles-rendererとReact Three Fiberを採用しています。PLATEAU、Google Photorealistic 3D Tiles、Cesium Ion等に対応しています。

github.com

OGC 3D Tiles形式の3D都市モデルや地形データを表示します。

Prop必須説明
srcstring-タイルセットJSONのURL
cesiumIon{ assetId: string }-Cesium Ion設定
googleCloud{}-Google Cloud設定
altstring-モデルの説明(アクセシビリティ用)
childrenReactNode-キャプション
heightstring | number-ビューアーの高さ(デフォルト: "400px")
cameraCameraConfig-カメラ設定(緯度・経度・高度)
regionRegionConfig-地域制限(指定範囲のタイルのみ読み込み)
debugboolean-デバッグ情報を表示(デフォルト: false)

srccesiumIongoogleCloudのいずれか1つを指定します。

<TilesViewer
  cesiumIon={{ assetId: "2602291" }}
  camera={{ lat: 35.6569, lon: 139.7464, height: 294 }}
  region={{ lat: 35.6616, lon: 139.7433, radius: 500 }}
  alt="PLATEAUの東京都3Dモデル"
>
  PLATEAU 3D都市モデル(ドラッグで回転、ホイールでズーム)
</TilesViewer>

PLATEAU 東京都 3D都市モデル(東京タワー周辺)

PanoramaViewer(パノラマ画像)

nisshi.dev独自実装

このコンポーネントはnisshi.devで独自に実装したものです。react-photo-sphere-viewerを採用しています。

github.com

パノラマ画像を360°ビューアーで表示します。ドラッグで視点を移動、ホイールでズーム操作が可能です。

Prop必須説明
srcstringパノラマ画像のパス
type"equirectangular" | "cylindrical"-投影方式(デフォルト: "equirectangular")
altstring-画像の説明(アクセシビリティ用)
childrenReactNode-キャプション
autoRotateSpeednumber-自動回転の速度(RPM、デフォルト: 1.0)
defaultZoomLevelnumber-デフォルトのズームレベル(0-100、デフォルト: 30)
defaultYawnumber-デフォルトの水平方向(度数、0-360、デフォルト: 0)

typeで投影方式を切り替えられます。Equirectangularは上下左右すべての方向を見回せる全天球パノラマ、CylindricalはiPhoneのパノラマ撮影のような水平方向のみのパノラマです。

<PanoramaViewer src="/images/panorama-360.jpg" alt="360°パノラマ">
  Equirectangular形式 - 上下左右すべての方向を見回せます
</PanoramaViewer>

<PanoramaViewer type="cylindrical" src="/images/panorama.jpg" alt="パノラマ">
  Cylindrical形式 - 水平方向のみ見回せます
</PanoramaViewer>

Equirectangular形式 - 上下左右すべての方向を見回せます

Cylindrical形式 - 水平方向のみ見回せます

VR180Viewer(VR180動画)

nisshi.dev独自実装

このコンポーネントはnisshi.devで独自に実装したものです。React Three Fiberを採用しています。

github.com

Side-by-Side(SBS)形式のVR180動画を180度半球に投影して表示します。マウスドラッグで視点を回転し、クリックで再生/一時停止を切り替えます。

Prop必須説明
srcstringVR180動画ファイルのパス(SBS形式)
altstring-動画の説明(アクセシビリティ用)
childrenReactNode-キャプション
heightstring | number-ビューアーの高さ(デフォルト: "500px")
mutedboolean-ミュート(デフォルト: true)
loopboolean-ループ再生(デフォルト: true)
<VR180Viewer src="/content/blog/example/vr180-video.mp4" alt="VR180動画">
  VR180動画(ドラッグで見回し、クリックで再生/一時停止)
</VR180Viewer>

VR180動画(ドラッグで見回し、クリックで再生/一時停止)

YouTube動画

nisshi.dev独自実装

このコンポーネントはnisshi.devで独自に実装したものです。@next/third-parties/googleを採用しています。

github.com

YouTubeのURLを単独行に書くと埋め込みプレーヤーになります。

https://www.youtube.com/watch?v=Vxtr-JzaePY

X(Twitter)の投稿

nisshi.dev独自実装

このコンポーネントはnisshi.devで独自に実装したものです。react-tweetを採用しています。

github.com

XのポストURLで埋め込み表示されます。

https://x.com/nisshi_dev/status/1697919798217200076

MediaGrid(メディアグリッド)

nisshi.dev独自実装

このコンポーネントはnisshi.devで独自に実装したものです。

メディア要素を横並びに配置するグリッドコンポーネントです。画像、Tweet、YouTube、LinkCardなど様々な要素に対応しています。

Prop必須説明
cols / columns2 | 3 | 4-列数(デフォルト: 2)
gap"sm" | "md" | "lg"-要素間のギャップ(デフォルト: "md")
align"start" | "center"-垂直方向の配置(デフォルト: "start")
childrenReactNode子要素
<MediaGrid cols={2}>
  ![画像1](https://pbs.twimg.com/media/G0Hwhu-bUAEbQBC?format=jpg&name=small)
  ![画像2](https://pbs.twimg.com/media/G0Hwhu-bUAEbQBC?format=jpg&name=small)
</MediaGrid>

3列レイアウト

<MediaGrid cols={3} gap="sm">
  ![画像1](https://pbs.twimg.com/media/G0Hwhu-bUAEbQBC?format=jpg&name=small)
  ![画像2](https://pbs.twimg.com/media/G0Hwhu-bUAEbQBC?format=jpg&name=small)
  ![画像3](https://pbs.twimg.com/media/G0Hwhu-bUAEbQBC?format=jpg&name=small)
</MediaGrid>

Figureと組み合わせ

<MediaGrid>
  <Figure caption="リアル会場">
    ![リアル](./real.jpg)
  </Figure>
  <Figure caption="VR会場">
    ![VR](./vr.jpg)
  </Figure>
</MediaGrid>

DesktopOnly(デスクトップ専用)

nisshi.dev独自実装

このコンポーネントはnisshi.devで独自に実装したものです。

モバイルではメモリ制限(特にiOS Safari)でクラッシュする可能性があるコンテンツをデスクトップ専用にするラッパーです。モバイルではフォールバックリンクを表示します。

Prop必須説明
childrenReactNodeデスクトップで表示するコンテンツ
fallbackUrlstringモバイル用フォールバックURL
fallbackTitlestring-モバイル用フォールバックタイトル
widthstring | number-
heightstring | number-高さ
<DesktopOnly
  fallbackUrl="https://example.com/embed"
  fallbackTitle="埋め込みコンテンツ"
>
  <iframe src="https://example.com/embed" />
</DesktopOnly>

Mermaid(ダイアグラム)

nisshi.dev独自実装

このコンポーネントはnisshi.devで独自に実装したものです。mermaidを採用しています。

github.com

Mermaid記法でフローチャートや図を描けます。

```mermaid
graph TD
    A[開始] --> B{条件分岐}
    B -->|Yes| C[処理A]
    B -->|No| D[処理B]
    C --> E[終了]
    D --> E
```

シーケンス図


テーブル

| 機能 | 説明 | 対応状況 |
|------|------|----------|
| MDX | Markdownの拡張構文 | ✅ |
| シンタックスハイライト | コードの色付け | ✅ |
| 数式 | KaTeX による数式表示 | ✅ |
機能説明対応状況
MDXMarkdownの拡張構文
シンタックスハイライトコードの色付け
数式KaTeX による数式表示

Frontmatter(記事メタデータ)

各記事の先頭にメタデータを記述します。

---
title: 記事のタイトル
description: 記事の説明文(SEO・OGPに使用)
subtitle: サブタイトル(オプション)
type: tech  # tech, report, tutorial, idea, diary
topics: ["Next.js", "React"]  # タグ
createdAt: 2025-01-01
published: true
featured: false  # 注目記事
archived: false  # アーカイブ済み
ogImage: /og/custom-og.png  # カスタムOGP画像(省略時は自動生成)
---

参考


新しいコンポーネントが追加された際は、このページも随時更新していきます。 「このコンポーネントも追加したら?」などのアイデアがあれば、ぜひ下のコメント欄で教えてください!

nisshi-dev
nisshi-dev

VRが好きなWebエンジニア。WebXRやVR・機械加工などの技術が好きでものづくりしている。WebXR JPというコミュニティやWeb技術集会というVR空間内の技術イベントを運営中。

コメント

この記事についてのご意見・ご質問をお気軽にどうぞ

ニックネーム:
匿名
コメントを読み込み中...