
nisshi.devブログで使えるMDX記法紹介
このページは実装したソースコードを元に Claude Code Agent Skills(Claude Opus 4.6)で自動生成し、著者(nisshi-dev)がレビュー・修正して公開しています。
このブログは、MDX記法で記事を書けるように環境構築しています。Fumadocsというドキュメントフレームワークをベースに、独自のremarkプラグインやReactコンポーネントを追加しており、3Dモデルなどのインタラクティブコンテンツも記事に直接埋め込めます。
このページでは、使える記法とコンポーネントをプレビュー付きで紹介します。自分のMDXブログで同様のことを実現したい方の参考になれば幸いです。
なお、UIコンポーネントカタログ(Storybook)は以下で公開しているので、興味があればご覧ください。
基本的なMarkdown構文
見出し
## 見出し2
### 見出し3
#### 見出し4テキスト装飾
**太字テキスト**
*斜体テキスト*
~~取り消し線~~
`インラインコード`太字テキスト、斜体テキスト、取り消し線、インラインコード
リスト
- 箇条書き1
- 箇条書き2
- ネストした項目
1. 番号付きリスト1
2. 番号付きリスト2- 箇条書き1
- 箇条書き2
- ネストした項目
- 番号付きリスト1
- 番号付きリスト2
引用
> これは引用文です。
> 複数行にまたがることもできます。これは引用文です。 複数行にまたがることもできます。
リンク
外部リンクと内部リンクで表示が異なります。外部リンクには自動的にリンク先が外部サイトであることを示すマーク(↗)が付きます。
外部リンク
[Google](https://google.com)内部リンク
[ブログ一覧](/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>;
}
```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"); シンタックスハイライト
def hello_world():
print("Hello, World!")
hello_world()npm install my-package{
"name": "my-project",
"version": "1.0.0"
}パッケージインストール
npm/yarn/pnpm/bunの切り替えタブ付きで表示します。
```package-install
my-package
```npm install fumadocs-uiTypeScript ⇔ 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 / tip | infoのエイリアス |
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は省略可能
リンクなしの説明カードも作れます
Link Card(リンクプレビュー)
nisshi.dev独自実装
このコンポーネントはnisshi.devで独自に実装したものです。OGP情報を自動取得してリンクカードを表示します。
URLを単独行に書くと、自動的にOGP付きリンクカードになります。
https://nextjs.org
https://fumadocs.dev
https://github.com/honojs/hono手動指定
LinkCardコンポーネントで手動指定も可能です。
| Prop | 型 | 必須 | 説明 |
|---|---|---|---|
| url | string | ✅ | リンク先URL |
| title | string | - | タイトル(指定するとOGP取得をスキップ) |
| description | string | - | 説明文 |
| image | string | - | 画像URL |
<LinkCard
url="https://example.com"
title="サイトのタイトル"
description="サイトの説明文"
/>数式(KaTeX)
LaTeX記法で数式を書けます。
インライン
ピタゴラスの定理: $$c = \pm\sqrt{a^2 + b^2}$$ピタゴラスの定理:
ブロック
```math
E = mc^2
``````math
\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}
```メディア埋め込み
画像
nisshi.dev独自実装
画像はクリックで拡大表示できます。react-medium-image-zoomを採用しています。

Figure(キャプション付き画像)
nisshi.dev独自実装
このコンポーネントはnisshi.devで独自に実装したものです。
画像などにキャプションを付けるコンポーネントです。
| Prop | 型 | 必須 | 説明 |
|---|---|---|---|
| caption | ReactNode | ✅ | キャプション(説明文。文字列またはJSX) |
| children | ReactNode | ✅ | 子要素(画像など) |
| className | string | - | カスタムクラス名 |
<Figure caption="イベント会場の様子">

</Figure>Video(動画)
nisshi.dev独自実装
このコンポーネントはnisshi.devで独自に実装したものです。WebM形式の場合、自動的にMP4フォールバックを追加します。media-chromeを採用しています。
動画プレイヤーコンポーネントです。
| Prop | 型 | 必須 | 説明 |
|---|---|---|---|
| src | string | ✅ | 動画のURL |
| fallbackSrc | string | - | フォールバック用動画URL |
| alt | string | - | 代替テキスト(アクセシビリティ用) |
| poster | string | - | ポスター画像URL |
| autoPlay | boolean | - | 自動再生(デフォルト: false) |
| loop | boolean | - | ループ再生(デフォルト: false) |
| muted | boolean | - | ミュート(デフォルト: false) |
| children | ReactNode | - | キャプション |
<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)に対応しています。
GLB/GLTF形式の3Dモデルを表示します。カメラ操作で回転・ズーム・パンが可能です。
| Prop | 型 | 必須 | 説明 |
|---|---|---|---|
| src | string | ✅ | モデルファイルのパス |
| alt | string | - | モデルの説明(アクセシビリティ用) |
| children | ReactNode | - | キャプション |
| height | string | number | - | ビューアーの高さ(デフォルト: "400px") |
| autoRotate | boolean | - | 自動回転(デフォルト: false) |
| autoRotateSpeed | number | - | 自動回転速度(度/秒、デフォルト: 30) |
| ar | boolean | - | AR機能を有効化(デフォルト: true) |
| poster | string | - | ポスター画像のURL |
| iosSrc | string | - | 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)にも対応しています。
VRM形式の3Dアバターを表示します。OrbitControlsで回転・ズーム・パン操作が可能です。
| Prop | 型 | 必須 | 説明 |
|---|---|---|---|
| src | string | ✅ | VRMファイルのパス |
| alt | string | - | モデルの説明(アクセシビリティ用) |
| children | ReactNode | - | キャプション |
| height | string | number | - | ビューアーの高さ(デフォルト: "350px") |
| autoRotate | boolean | - | 自動回転(デフォルト: false) |
| autoRotateSpeed | number | - | 自動回転の速度(デフォルト: 1.0) |
| scale | number | - | モデルのスケール(デフォルト: 1) |
| cameraPosition | [number, number, number] | - | カメラの初期位置(デフォルト: [0, 1.5, 3]) |
| debug | boolean | - | デバッグ情報を表示(デフォルト: false) |
<VrmViewer src="/models/avatar.vrm" alt="VRMアバター">
VRMアバター(ドラッグで回転、ホイールでズーム)
</VrmViewer>VRMアバター(ドラッグで回転、ホイールでズーム)
SplatViewer(3D Gaussian Splat)
nisshi.dev独自実装
このコンポーネントはnisshi.devで独自に実装したものです。@sparkjsdev/sparkとReact Three Fiberを採用しています。
3D Gaussian Splatting形式のシーンを表示します。.ply, .spz, .splat, .ksplat, .sog形式に対応しています。
| Prop | 型 | 必須 | 説明 |
|---|---|---|---|
| src | string | ✅ | Splatファイルのパス |
| alt | string | - | モデルの説明(アクセシビリティ用) |
| children | ReactNode | - | キャプション |
| height | string | number | - | ビューアーの高さ(デフォルト: "350px") |
| autoRotate | boolean | - | 自動回転(デフォルト: false) |
| autoRotateSpeed | number | - | 自動回転の速度(デフォルト: 1.0) |
| scale | number | - | モデルのスケール(デフォルト: 1) |
| cameraPosition | [number, number, number] | - | カメラの初期位置(デフォルト: [0, 0, 5]) |
| debug | boolean | - | デバッグ情報を表示(デフォルト: 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等に対応しています。
OGC 3D Tiles形式の3D都市モデルや地形データを表示します。
| Prop | 型 | 必須 | 説明 |
|---|---|---|---|
| src | string | - | タイルセットJSONのURL |
| cesiumIon | { assetId: string } | - | Cesium Ion設定 |
| googleCloud | {} | - | Google Cloud設定 |
| alt | string | - | モデルの説明(アクセシビリティ用) |
| children | ReactNode | - | キャプション |
| height | string | number | - | ビューアーの高さ(デフォルト: "400px") |
| camera | CameraConfig | - | カメラ設定(緯度・経度・高度) |
| region | RegionConfig | - | 地域制限(指定範囲のタイルのみ読み込み) |
| debug | boolean | - | デバッグ情報を表示(デフォルト: false) |
src、cesiumIon、googleCloudのいずれか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を採用しています。
パノラマ画像を360°ビューアーで表示します。ドラッグで視点を移動、ホイールでズーム操作が可能です。
| Prop | 型 | 必須 | 説明 |
|---|---|---|---|
| src | string | ✅ | パノラマ画像のパス |
| type | "equirectangular" | "cylindrical" | - | 投影方式(デフォルト: "equirectangular") |
| alt | string | - | 画像の説明(アクセシビリティ用) |
| children | ReactNode | - | キャプション |
| autoRotateSpeed | number | - | 自動回転の速度(RPM、デフォルト: 1.0) |
| defaultZoomLevel | number | - | デフォルトのズームレベル(0-100、デフォルト: 30) |
| defaultYaw | number | - | デフォルトの水平方向(度数、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を採用しています。
Side-by-Side(SBS)形式のVR180動画を180度半球に投影して表示します。マウスドラッグで視点を回転し、クリックで再生/一時停止を切り替えます。
| Prop | 型 | 必須 | 説明 |
|---|---|---|---|
| src | string | ✅ | VR180動画ファイルのパス(SBS形式) |
| alt | string | - | 動画の説明(アクセシビリティ用) |
| children | ReactNode | - | キャプション |
| height | string | number | - | ビューアーの高さ(デフォルト: "500px") |
| muted | boolean | - | ミュート(デフォルト: true) |
| loop | boolean | - | ループ再生(デフォルト: true) |
<VR180Viewer src="/content/blog/example/vr180-video.mp4" alt="VR180動画">
VR180動画(ドラッグで見回し、クリックで再生/一時停止)
</VR180Viewer>VR180動画(ドラッグで見回し、クリックで再生/一時停止)
YouTube動画
nisshi.dev独自実装
このコンポーネントはnisshi.devで独自に実装したものです。@next/third-parties/googleを採用しています。
YouTubeのURLを単独行に書くと埋め込みプレーヤーになります。
https://www.youtube.com/watch?v=Vxtr-JzaePYX(Twitter)の投稿
nisshi.dev独自実装
このコンポーネントはnisshi.devで独自に実装したものです。react-tweetを採用しています。
XのポストURLで埋め込み表示されます。
https://x.com/nisshi_dev/status/1697919798217200076MediaGrid(メディアグリッド)
nisshi.dev独自実装
このコンポーネントはnisshi.devで独自に実装したものです。
メディア要素を横並びに配置するグリッドコンポーネントです。画像、Tweet、YouTube、LinkCardなど様々な要素に対応しています。
| Prop | 型 | 必須 | 説明 |
|---|---|---|---|
| cols / columns | 2 | 3 | 4 | - | 列数(デフォルト: 2) |
| gap | "sm" | "md" | "lg" | - | 要素間のギャップ(デフォルト: "md") |
| align | "start" | "center" | - | 垂直方向の配置(デフォルト: "start") |
| children | ReactNode | ✅ | 子要素 |
<MediaGrid cols={2}>


</MediaGrid>3列レイアウト
<MediaGrid cols={3} gap="sm">



</MediaGrid>Figureと組み合わせ
<MediaGrid>
<Figure caption="リアル会場">

</Figure>
<Figure caption="VR会場">

</Figure>
</MediaGrid>DesktopOnly(デスクトップ専用)
nisshi.dev独自実装
このコンポーネントはnisshi.devで独自に実装したものです。
モバイルではメモリ制限(特にiOS Safari)でクラッシュする可能性があるコンテンツをデスクトップ専用にするラッパーです。モバイルではフォールバックリンクを表示します。
| Prop | 型 | 必須 | 説明 |
|---|---|---|---|
| children | ReactNode | ✅ | デスクトップで表示するコンテンツ |
| fallbackUrl | string | ✅ | モバイル用フォールバックURL |
| fallbackTitle | string | - | モバイル用フォールバックタイトル |
| width | string | number | - | 幅 |
| height | string | number | - | 高さ |
<DesktopOnly
fallbackUrl="https://example.com/embed"
fallbackTitle="埋め込みコンテンツ"
>
<iframe src="https://example.com/embed" />
</DesktopOnly>Mermaid(ダイアグラム)
nisshi.dev独自実装
このコンポーネントはnisshi.devで独自に実装したものです。mermaidを採用しています。
Mermaid記法でフローチャートや図を描けます。
```mermaid
graph TD
A[開始] --> B{条件分岐}
B -->|Yes| C[処理A]
B -->|No| D[処理B]
C --> E[終了]
D --> E
```シーケンス図
テーブル
| 機能 | 説明 | 対応状況 |
|------|------|----------|
| MDX | Markdownの拡張構文 | ✅ |
| シンタックスハイライト | コードの色付け | ✅ |
| 数式 | KaTeX による数式表示 | ✅ || 機能 | 説明 | 対応状況 |
|---|---|---|
| MDX | Markdownの拡張構文 | ✅ |
| シンタックスハイライト | コードの色付け | ✅ |
| 数式 | 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画像(省略時は自動生成)
---参考
新しいコンポーネントが追加された際は、このページも随時更新していきます。 「このコンポーネントも追加したら?」などのアイデアがあれば、ぜひ下のコメント欄で教えてください!
VRが好きなWebエンジニア。WebXRやVR・機械加工などの技術が好きでものづくりしている。WebXR JPというコミュニティやWeb技術集会というVR空間内の技術イベントを運営中。
コメント
この記事についてのご意見・ご質問をお気軽にどうぞ