HtmlPreview
ビューポート切り替えとソースコード表示を備えたインタラクティブなHTML/CSSプレビューコンポーネント。
<HtmlPreview> は、分離された iframe 内で HTML/CSS のライブデモを描画するコンポーネントです。ビューポートプリセット(Mobile / Tablet / Full)とシンタックスハイライト付きの折りたたみ可能なソースコードパネルを備えています。すべての MDX ファイルでインポートなしで使用できます。
基本的な使い方
<HtmlPreview
title="基本的なボックス"
html={`
<div class="box">Hello, world!</div>
`}
css={`
.box {
padding: 24px;
background: #3b82f6;
color: #fff;
border-radius: 8px;
font-family: system-ui, sans-serif;
text-align: center;
}
`}
/>レスポンシブレイアウト
ビューポートボタン(Mobile / Tablet / Full)を使って、異なる幅でコンテンツがどのように変化するかを確認できます。プレビュー領域の右下にあるドラッグハンドルでリサイズすることもできます。
HTML のみ
css プロップを指定しない場合は、HTML のソースのみが表示されます。
デフォルトでコードを表示
defaultOpen を指定すると、ソースコードが最初から展開された状態で表示されます。
<button class="btn">Click me</button>.btn {
padding: 10px 20px;
background: #8b5cf6;
color: #fff;
border: none;
border-radius: 6px;
font-size: 14px;
font-family: system-ui, sans-serif;
cursor: pointer;
}
.btn:hover {
background: #7c3aed;
}固定高さ
height プロップを使って、自動調整の代わりに iframe の高さを固定できます。
外部リソース
CSS フレームワーク、Web フォント、スクリプトなどの外部リソースをプレビューに読み込めます。settings.ts でグローバルに設定するか、コンポーネントのプロップで個別に指定します。
グローバル設定
src/ で htmlPreview を設定すると、すべてのプレビューにリソースが適用されます:
htmlPreview: {
head: `<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP&display=swap">`,
css: `body { font-family: 'Noto Sans JP', sans-serif; }`,
js: `console.log('preview loaded');`,
}コンポーネント単位のプロップ
head と js プロップを使って、個別のプレビューにリソースを追加できます。グローバル設定の後にマージされます。
<HtmlPreview
title="JS 付き"
html={`
<div id="output">待機中...</div>
`}
css={`
#output {
padding: 16px;
font-family: system-ui, sans-serif;
color: #334155;
}
`}
js={`
document.getElementById('output').textContent = 'JS から Hello!';
`}
/>セキュリティと sandbox プロップ
プレビューは分離された <iframe srcdoc> 内に描画されます。その sandbox 属性は、プレビューにスクリプトが含まれる場合(js プロップまたは head 内の <script>)は allow-scripts allow-same-origin、含まれない場合は allow-same-origin をデフォルトとします。
:::danger[信頼の前提]
allow-scripts と allow-same-origin を組み合わせると、iframe のサンドボックスは実質的に無効化されます — プレビュー内のスクリプトが親ページのオリジンを共有し、親ドキュメントにアクセスできます。zudo-doc がこのデフォルトを採用しているのは、プレビューの内容が作成者が信頼できる MDX であるためで、また allow-same-origin が高さの自動計測を可能にしているためです。
半信頼またはユーザー投稿の HTML を描画するプロジェクトでは、sandbox プロップでより厳しい値に上書きしてください。
:::
<!-- 最も厳格: スクリプト実行なし、オリジンは不透明 -->
<HtmlPreview html={untrusted} sandbox="" height={400} />
<!-- スクリプトは許可するがオリジンは不透明(親にアクセス不可) -->
<HtmlPreview html={untrusted} sandbox="allow-scripts" height={400} />allow-same-origin を外すと iframe のオリジンが不透明になり、親から iframe.contentDocument を読み取れなくなります — つまり高さの自動調整が無効になります。厳しい sandbox を指定するときは、必ず固定の height も併用してください。空文字列 "" はそのまま尊重され、プロップを省略したときだけ計算済みのデフォルトにフォールバックします。
Props
| プロップ | 型 | デフォルト | 説明 |
|---|---|---|---|
html | string | (必須) | プレビュー iframe 内に描画する HTML コンテンツ |
css | string | undefined | プレビュー iframe 内に適用する CSS スタイル |
head | string | undefined | <head> に挿入する生の HTML(リンク、メタ、フォント) |
js | string | undefined | プレビュー iframe 内で実行する JavaScript |
title | string | undefined | プレビューヘッダーバーに表示するタイトル |
height | number | auto | iframe の固定高さ(ピクセル)。省略時はコンテンツに合わせて自動調整 |
defaultOpen | boolean | false | ソースコードパネルをデフォルトで展開表示する |
sandbox | string | auto | iframe の sandbox 属性。省略時は計算済みのデフォルト(スクリプトありなら allow-scripts allow-same-origin、なしなら allow-same-origin)。信頼できないコンテンツにはより厳しい値を指定 — ただし allow-same-origin を外すと高さ自動調整が無効になるため height も併せて指定する |
サポートされている言語
ソースコードパネルは軽量な Shiki インスタンスを使用しており、以下の言語に対応しています:
html— HTML パネルおよび Head パネルcss— CSS パネルjavascript— JS パネル
サポートされていない言語はプレーンテキスト(ハイライトなし)にフォールバックします。これは標準のコードブロックで利用可能な言語一覧より小さなサブセットです。
注意事項
プレビューは CSS リセット(Tailwind v4 preflight)を含む分離された
<iframe>内で描画されるため、スタイルが外部に漏れることはありません。プレビューはデフォルトで
sandbox="allow-same-origin"(jsプロップまたは<script>がある場合はsandbox="allow-scripts allow-same-origin")を使用し、contentDocument経由で iframe の高さを自動同期します。srcdocの内容は作成者が管理する MDX です。信頼できないコンテンツにはsandboxプロップで上書きしてください — 上記のセキュリティとsandboxプロップを参照。settings.htmlPreviewのグローバルリソースは、コンポーネント単位のプロップの前に挿入されます。html、css、jsプロップはインデント付きのテンプレートリテラルに対応しています。先頭の空白はソースコード表示時に自動的に除去されます。クライアントサイドのハイドレーションはコンポーネントラッパーにより自動的に処理されるため、MDX 内で
client:loadディレクティブを付ける必要はありません。