/docs/authoring
MDXでスライドを書く
利用できるMarkdown、MDX、hono-decks独自の記法をまとめています。
デッキごとにディレクトリを分ける
decks/<slug>/deck.mdxが基本形です。ディレクトリ名がURLの:slugになります。たとえばdecks/launch/deck.mdxは/decks/launchで表示されます。
ファイル先頭の---ブロックはデッキ情報、その後の区切り線は新しいスライドの開始を表します。スライド内の水平線として単独の---は使えません。
---
title: Hono at the edge
transition: fade
---
# Hono at the edge
---
title: Runtime boundary
layout: statement
---
Node for I/O. Hono for routes.本文はGFMとMDXで書く
CommonMarkとGFM(テーブル、タスクリスト、打ち消し線、自動リンク)を使えます。MDXではJSX要素や式も記述できます。
# Runtime boundary
Use **bold**, *emphasis*, `inline code`, and [links](https://hono.dev/).
- Node for build-time I/O
- Hono for runtime routes
- [x] Compile the deck
- [ ] Deploy the Worker
| Layer | Responsibility |
| :-- | :-- |
| Node | Build-time I/O |
| Hono | Runtime routes |
~~Filesystem access at runtime~~
> Keep the Worker bundle filesystem-free.
```ts
const runtime = "Hono"
```- コードフェンス
- 開始行に
ts、tsx、cssなどの言語名を付けると、スライド内でシンタックスハイライトされます。 - MDX
- JSXコンポーネント、props、式を使えます。
importとexportはファイル先頭にまとめます。
デッキ全体と各スライドの設定を分ける
ファイル先頭のフロントマターはデッキ全体に適用されます。区切り線の直後に置いたフロントマターは、そのスライドだけに適用されます。未定義のキーはmetaに残り、コンパイル時に警告が表示されます。
- デッキ
title,description,author,tags,date,theme,transition,transitionDuration,transitionEasing,draft,assets,presenter- スライド
title,layout,class,notes,background,transition,transitionDuration,transitionEasing- トランジション
none,fade,fade-out,slide-left,slide-right,slide-up,slide-down,view-transition- レイアウト
default、中央配置のcoverとstatementが標準です。独自名はlayout-<name>クラスとしてtheme.cssから指定できます。
fireで内容を1つずつ表示する
コンポーネントにfireを付けると、送り操作に合わせて記述順に表示されます。Markdownには:::fire、リストには:::fire{each="item"}を使います。複数のJSX要素を同時に表示するときは、まとめて<Fire>で囲みます。fireはコンパイル時に取り除かれ、コンポーネントのpropsには渡りません。
<Card fire />
<Chart fire="scale" at="2" />
:::fire{at="+2"}
Markdown block
:::
:::fire{each="item" depth="2" every="2"}
- Parent one
- Child one
- Parent two
- Child two
:::
<Fire effect="fade-up">
<Heading />
<Description />
</Fire>段階表示の考え方とat、depth、everyの仕組みは、Slidevのv-clickとv-clicksを一部参考にしています。ただし、記法と実装はhono-decks独自であり、Slidevとの互換性は保証しません。at="2"は絶対位置、at="+2"は現在位置から2段先を指定します。リストでは、depthで対象の階層、everyで1回に表示する項目数を指定します。どちらも既定値は1です。
表示効果を選ぶ
コンポーネントではfire="scale"、:::fireではeffect="scale"と指定します。標準の効果はnone、fade、fade-up、scaleです。独自の効果はtheme.cssで定義します。
<Chart fire="blur-in" />
:::fire{effect="blur-in"}
Markdown block
:::[data-fire-effect="blur-in"] {
--fire-transform: scale(.98);
--fire-filter: blur(12px);
--fire-duration: .32s;
--fire-easing: ease-out;
}発表者ノートを書く
notes: |に書いた複数行テキストとMDXコメントは、発表者ノートにまとめられ、スライド本文には表示されません。MDXコメントは、コードの補足として書いた場合もノートとして扱われます。
---
notes: |
Explain why generation runs before deployment.
---
# Build once, serve anywhere
{/* Mention the generated module boundary. */}まずサーバーコンポーネントを使う
components/index.tsxの名前付きエクスポートは、同じデッキのMDXからタグとして使えます。デッキごとに登録されるため、別のデッキと同じ名前でも衝突しません。
// decks/welcome/components/index.tsx
export function Metric(props: { value: string; label: string }) {
return <figure>
<strong>{props.value}</strong>
<figcaption>{props.label}</figcaption>
</figure>
}<Metric value="18 ms" label="Response time" />ブラウザ操作が必要な部品だけをIslandにする
components/client/index.tsxはクリックや状態管理が必要な部品だけに使います。クライアント用コードは自動生成されるため、通常は配信用ルートを追加する必要はありません。
// decks/welcome/components/client/index.tsx
import { useState } from "hono/jsx/dom"
export function Counter() {
const [count, setCount] = useState(0)
return <button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
}画像を置き、外部コンテンツを埋め込む
decks/launch/assets/に置いた画像は、deck.mdxからの相対パスで指定します。youtube、x、card、embed、iframeは専用記法を使います。

@[youtube](https://www.youtube.com/watch?v=VIDEO_ID)
@[x](https://x.com/honojs/status/POST_ID)
@[card](https://hono.dev/docs/)
@[embed](https://example.com/demo)
@[iframe](https://example.com/demo)URLだけの行は通常のリンクになります。外部iframeを公開する前にCSPと許可オリジンを設定してください。R2配信へ変える場合は、MDXを変えずにwithR2Assets()で取得元を差し替えます。
デッキ単位でテーマを追加する
deck.mdxと同じディレクトリにtheme.cssを置くと、そのデッキだけに適用されます。まずCSS変数で色を調整し、必要な部分だけ通常のセレクターを追加します。
/* decks/welcome/theme.css */
:root {
--hono-decks-accent-color: #ff5b1a;
}
.slide h1 {
text-wrap: balance;
}devコマンドで変更を自動反映する
npm run devViteまたはWranglerのdev実行中は、保存したMDXが自動で再コンパイルされ、成功後にブラウザへ反映されます。npm run decks:compileは、CIやコンパイラーだけを単独で確認するときに使います。コンパイルエラーには対象ファイルとスライド番号が表示されます。