hono-decks 1.0.4 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ja.md CHANGED
@@ -4,7 +4,175 @@
4
4
 
5
5
  Hono と Cloudflare Workers 上で MDX のスライドを配信するためのライブラリです。ビルド時に MDX を TypeScript module へ変換し、Worker runtime ではファイルシステムや compiler を読み込みません。
6
6
 
7
- ## Quick start
7
+ ## Hono+Vite/HonoX:init で接続する
8
+
9
+ 既存のアプリに `hono-decks` をインストールし、構成に合わせて初期設定します。
10
+
11
+ ```sh
12
+ npm install hono-decks
13
+
14
+ # Hono+Vite
15
+ npx hono-decks init --framework hono
16
+
17
+ # HonoX の場合はこちら
18
+ npx hono-decks init --framework honox
19
+
20
+ # 以後は既存のコマンドを使う
21
+ npm run dev
22
+ npm run build
23
+ ```
24
+
25
+ どちらも、既存の Vite 設定を保持して自動コンパイルを登録し、
26
+ `hono-decks.config.ts`、`src/decks.ts`、サンプルの
27
+ `decks/welcome/deck.mdx` を作ります。生成ファイルがない状態からでも
28
+ 通常の `dev`/`build` だけで動き、手動 `compile` やビルドコマンドの変更は不要です。
29
+ 生成コードは Vite の仮想モジュールとして扱い、ファイルへ出力しません。Void 用のアダプターは必要ありません。
30
+
31
+ | 構成 | アプリへの接続 |
32
+ | --- | --- |
33
+ | `--framework hono` | 既存の Hono エントリーにルーターを追加。既存のミドルウェアとルートを保持 |
34
+ | `--framework honox` | `createApp()` に設定連動のルートを追加。既存のオプション、ページ、ミドルウェアを保持 |
35
+
36
+ 公開先は `/slides/welcome` です。同名の既存デッキがあれば、サンプルには
37
+ 空いている名前を選びます。既存の `.mdx`、コンポーネント、画像はそのまま使えます。
38
+
39
+ Hono では、`src/index.ts`/`.tsx`/`.js`/`.mts`/`.mjs` または
40
+ `src/app.ts`/`.tsx`/`.js` の候補が1つなら自動検出します。
41
+ 独自の場所にある場合や複数の候補がある場合は、
42
+ `--entry src/server.ts` のように指定してください。
43
+ 自動接続は `const app = new Hono()` で作ったアプリを default export する形式に対応します。
44
+ 先行する catch-all/動的ルートなど、安全に接続できない構成ではファイルを変更せず、
45
+ 手動接続の案内を表示します。
46
+
47
+ HonoX は標準の `app/routes` と、`app/server.ts` で `createApp()` を default export
48
+ する構成に対応します。`init` は `src/honox-decks.ts` を作り、既存の
49
+ `createApp()` オプションを包みます。HonoX の公開 `ROUTES` API に設定から
50
+ ルートを追加するため、**公開パスは `mountPath` 一か所の変更で切り替わります**。
51
+ ルート用ディレクトリを作成・改名する必要はありません。既存ルートと重なる場合はエラーにします。
52
+ 開発中の公開パス変更では、コンパイル後に Vite を自動で再起動してルートを切り替えます。
53
+ 生成する HonoX 接続ファイルには、`import.meta.glob` によるルート探索と
54
+ `hono-decks/honox` の `withHonoXDecks()` 呼び出しだけを置きます。
55
+ ルートの合成と衝突検査はパッケージが担当し、動的ルートや catch-all との衝突も検出します。
56
+ この処理の修正は、アプリ側を再生成せずパッケージ更新で受け取れます。
57
+ `createApp()` のオプション、ミドルウェア、明示的な `ROUTES` は保持します。
58
+ `--config config/slides.ts` で設定ファイルの場所を変えることもできます。
59
+
60
+ ## Void:通常の dev/build で使う
61
+
62
+ 既存の Void アプリに hono-decks と対応する Hono Markdown アダプターを
63
+ インストールし、初回だけ `init` を実行します。
64
+
65
+ ```sh
66
+ npx hono-decks init --framework void --install
67
+ npm run dev
68
+ # 本番用のビルド
69
+ npm run build
70
+ ```
71
+
72
+ この連携には `void-plugin-hono-jsx@^0.4.0` の standalone compiler/client export
73
+ が必要です。`--install` は対応範囲のアダプターを選びます。
74
+ `--install` を省略する場合は、Markdown 用の任意 peer も必要です:
75
+ `markdown-exit@^1.3.0 yaml@^2.9.1 markdown-it-container@^4.0.0 shiki@^4.5.0 @shikijs/transformers@^4.5.0`。
76
+ 動作確認した組み合わせは Void 1.1.11、Vite 8.3.4、Hono 4.13.13 です。
77
+
78
+ `--install` は npm/pnpm/Yarn/Bun を packageManager または lockfile から判定し、
79
+ 不足する依存だけを追加します。互換性のない既存バージョンは自動更新せずエラーにします。
80
+ Yarn は node_modules linker を対象とし、PnP は手動インストールを使ってください。
81
+ 依存を自分で管理する場合は `--install` を省略できます。ローカルでビルドしたアダプターは
82
+ `--adapter /absolute/path/void-plugin-hono-jsx.tgz` で指定できます。
83
+ アプリ設定の衝突はインストール前に検査し、インストール失敗時は接続ファイルを作りません。
84
+ パッケージマネージャーによる依存・lockfileの変更は残る場合があります。
85
+
86
+ `init --framework void` は、既存のルート `vite.config.*` の default export を
87
+ `withHonoDecks()` で包み、次のファイルを作ります。
88
+
89
+ - `hono-decks.config.ts`:公開パス `/slides`、入力先 `decks`、Hono Markdown の有効化
90
+ - `src/decks.ts`:アプリ側で編集できる接続ファイル
91
+ - `middleware/hono-decks.ts`:スライド配下のルーティング、Markdown の CSS、開発時の自動更新
92
+ - `decks/welcome/deck.md` と `Counter.tsx`:`/slides/welcome` で開ける対話可能なサンプル
93
+
94
+ 既存の `welcome` デッキがある場合は、`welcome-2` などの空いている名前を選び、
95
+ URL を表示します。既存の Markdown/MDX はそのまま保持します。
96
+
97
+ サンプルを編集するか、`decks` に `.md`/`.mdx` を追加してください。
98
+ 既存の Vite の `dev`/`build` が自動でコンパイルします。生成ファイルが
99
+ ない状態から起動する場合も、手動 `compile`、別の監視プロセス、
100
+ `package.json` のコマンド変更は不要です。Vite が生成コードをメモリ上で扱うため、
101
+ 生成用ディレクトリや、その `.gitignore` 登録も不要です。
102
+ 既存の Void のエントリー、ルート、package scripts は保持します。
103
+ 公開パスは既存ルートと重ならないものを選び、必要に応じてアプリのアクセス制御を適用してください。
104
+
105
+ 書き込み前に依存パッケージと出力先の衝突を確認します。既存の接続ファイルは
106
+ 上書きせず、hono-decks の二重登録も行いません。ESM の default export で
107
+ 設定を返すオブジェクト、式、非同期関数に対応します。対応できない設定では
108
+ ファイルを変更せず、`honoDecks()` を手動で登録する方法を表示します。
109
+ `--config config/slides.ts` で設定ファイルの場所を変更できます。
110
+ `--out`/`--generated` は、以下の汎用 init 向けのオプションです。
111
+
112
+ ## Markdown 内のクライアントコンポーネント
113
+
114
+ Hono Markdown では、別の登録ファイルを作らず、本文の import から自動登録できます。
115
+
116
+ ```md
117
+ <script>
118
+ import Counter from "./Counter.tsx" with { island: "load" };
119
+ </script>
120
+ ---
121
+ title: Interactive slide
122
+ ---
123
+ # デモ
124
+
125
+ <Counter label="Count" initial="2" />
126
+ ```
127
+
128
+ `Counter.tsx` は Hono JSX の default export です。`hono/jsx` の `useState` を使えます。
129
+ island はサーバーで初期描画し、`load`/`visible`/`idle`/`media:(query)` の条件で
130
+ ブラウザー上で動かします。`visible` はスライドがアクティブになってから監視します。
131
+ CSS import はコンパイル時に回収し、SSR・印刷ページにも含めます。
132
+ `useFrontmatter()` と `useMarkdownHeadings()` は各スライドの情報を返します。
133
+ クライアントへ渡すメタデータに秘密情報を含めないでください。
134
+
135
+ 対応範囲は相対 TSX/JSX の default import と、文字列・真偽値のリテラル属性です。
136
+ JSX 式、island タグの子要素、任意の script コードは未対応です。
137
+ 静的な部品は引き続き `with { component: "static" }` を使います。
138
+ 既存 MDX のクライアントコンポーネント登録方法は変わりません。
139
+
140
+ ## Vite の生成物と型チェック
141
+
142
+ Hono+Vite/HonoX/Void は、共通の `virtual:hono-decks` を入口にします。
143
+ `init` が作る `src/decks.ts` は、この仮想モジュールへ接続します。
144
+
145
+ ```ts
146
+ /// <reference types="hono-decks/vite-env" />
147
+ import { decks } from "virtual:hono-decks";
148
+
149
+ export { decks };
150
+ ```
151
+
152
+ `decks` は `hono-decks.config.ts` を適用したコレクションです。
153
+ `decks.router()`、`decks.paths()` などの API は従来どおり使えます。
154
+ 仮想モジュールには必要に応じて設定を適用する `createDecks(config)` もあります。
155
+ 型定義はパッケージに同梱しているため、初回の `dev`/`build` 前でも型チェックできます。
156
+
157
+ 通常は `decks/` の原稿・画像・部品と設定ファイルを編集します。
158
+ Vite はコンパイル結果をメモリ上のモジュールとして読み込み、ビルド時にアプリへ取り込みます。
159
+ `src/generated` の作成や直接 import、`build.outDir` の指定は不要です。
160
+ 明示的に設定した OGP メタデータキャッシュは、従来どおり保存します。
161
+ 設定から import した別ファイルも監視するため、公開パスなどを分けて管理できます。
162
+ init の開発クライアントは Vite の `BASE_URL` を使います。ホストの開発サーバーが
163
+ Vite の URL を処理する構成では、base に合わせた既存のアセット除外設定も保持してください。
164
+
165
+ 既存の Vite 接続ファイルが生成先を直接 import している場合も、プラグインが
166
+ 設定された出力先を仮想モジュールへ解決します。生成 TypeScript を参照する
167
+ `.js` 拡張子の import も互換性を維持します。新しい接続では上記の固定の入口を推奨します。
168
+
169
+ Vite 以外で使う CLI の `hono-decks compile` と `compileDecks()` は、
170
+ 従来どおり `build.outDir`/`out` へファイルを書き出します。
171
+ コンパイル処理は両方式で共通です。実行環境にコンパイラーや Node のファイル操作は持ち込みません。
172
+
173
+ ## Hono/MDX の Quick start
174
+
175
+ Vite を使う Hono/HonoX/Void アプリでは、以下の手動コンパイル手順ではなく、上記の init を使ってください。
8
176
 
9
177
  ```bash
10
178
  bun add hono hono-decks
@@ -197,7 +365,7 @@ decks/product/
197
365
  index.tsx
198
366
  ```
199
367
 
200
- `components/index.tsx` は server-side JSX component、`components/client/index.tsx` は browser で hydrate する component です。`theme.css` はその deck だけに適用されます。画像は compile 時に検出され、`mountPath` と slug を使った public URL に書き換えられます。
368
+ `components/index.tsx` は server-side JSX component、`components/client/index.tsx` は browser で hydrate する component です。`theme.css` はその deck だけに適用されます。 テーマ未指定時は白背景と濃い文字色を使います。配色を変える場合は `theme.css` で `--hono-decks-background` と `--hono-decks-color` を合わせて指定してください。1920 × 1080 の固定キャンバス内では `px` や `rem` を使います。`vw` / `vh` はブラウザのズームに応じて内容の配置も変えてしまいます。画像は compile 時に検出され、`mountPath` と slug を使った public URL に書き換えられます。
201
369
 
202
370
  ## Embedding
203
371
 
@@ -243,7 +411,7 @@ export default defineDecksConfig({
243
411
 
244
412
  独自CDNを使う場合は `imagePath: ({ deck }) => \`https://cdn.example.com/${deck.slug}.png\`` のように resolver で上書きできます。`false` または未指定なら social metadata は出力しません。
245
413
 
246
- 生成処理は core に含まれません。`examples/ogp` では `hono-decks/node` の `compileDecks()` が返す manifest を Satori + resvg へ渡し、1200×630 PNG を Workers Static Assets へ保存します。Satori / resvg は example だけの依存で、Browser Rendering binding は不要です。Satori は TTF / OTF / WOFF を読み込めますが WOFF2 は扱えないため、対象言語の font file を build script から明示的に渡してください。
414
+ 生成処理は core に含まれません。`examples/ogp` では `hono-decks/node` の `compileDecks()` が返すデッキのメタデータを Satori + resvg へ渡し、1200×630 PNG を Workers Static Assets へ保存します。Satori / resvg は example だけの依存で、Browser Rendering binding は不要です。Satori は TTF / OTF / WOFF を読み込めますが WOFF2 は扱えないため、対象言語の font file を build script から明示的に渡してください。
247
415
 
248
416
  `build.ogpCacheFile` は `@[card](...)` が参照する外部サイトのメタデータキャッシュです。viewer 自身の share image とは別機能です。
249
417
 
@@ -290,3 +458,19 @@ app.route("/internal-slides", decksRouter({ source, dev: true }));
290
458
  - `examples/minimal`: standalone Worker の最小構成
291
459
  - `examples/basic`: R2、Browser Rendering、custom routes、client components
292
460
  - `examples/honox`: HonoX integration
461
+
462
+ ## Node ビルド結果と失敗時の復旧
463
+
464
+ `compileDecks()` の戻り値は `CompileDecksResult` です。出力先、生成された
465
+ `decks.ts` のパス、各デッキのメタデータ、スライドのモジュールパスを返します。
466
+ 描画には、生成された `decks.ts` の `createDecks()` を使ってください。
467
+ 戻り値をそのまま `defineDecks()` へ渡すコードは変更が必要です。
468
+ タイトル、警告、アセット、ノートを `result.decks` から読む処理は引き続き使えます。
469
+
470
+ 同期レンダラーは同期の描画関数を実行します。非同期の本文には非同期版を使うよう
471
+ エラーで案内し、描画できないビルド結果を渡した場合も空表示にせずエラーにします。
472
+
473
+ 生成処理とクライアント資産のビルドが完了してから、生成ファイルと OGP キャッシュを
474
+ 反映します。反映中に失敗した場合は、直前の内容へ戻します。OS やプロセスの停止時の
475
+ 一括反映、複数プロセスの同時実行は保証しません。復元自体に失敗した場合は、
476
+ 復旧用ファイルを残し、その場所をエラーに表示します。
package/README.md CHANGED
@@ -4,9 +4,173 @@ English | [日本語](https://github.com/ts-76/hono-decks/blob/main/packages/dec
4
4
 
5
5
  hono-decks serves MDX slide decks from Hono applications and Cloudflare Workers. It compiles MDX into TypeScript modules at build time, so the Worker runtime does not load the filesystem or the compiler.
6
6
 
7
- ## Quick start
7
+ ## Hono + Vite / HonoX: connect with init
8
+
9
+ Install hono-decks in an existing app and choose its integration:
10
+
11
+ ~~~sh
12
+ npm install hono-decks
13
+
14
+ # Hono + Vite
15
+ npx hono-decks init --framework hono
16
+
17
+ # Use this instead for HonoX
18
+ npx hono-decks init --framework honox
19
+
20
+ # Keep using the app's existing commands
21
+ npm run dev
22
+ npm run build
23
+ ~~~
24
+
25
+ Both modes preserve the existing Vite config while adding automatic compilation,
26
+ create `hono-decks.config.ts`, `src/decks.ts`, and a sample
27
+ `decks/welcome/deck.mdx`. Generated code stays in Vite virtual modules and is not written to disk.
28
+ Normal `dev` and `build` work from a checkout without generated files. There is
29
+ no manual `compile` step or package script change. Neither mode needs the Void adapter.
30
+
31
+ | Mode | Application connection |
32
+ | --- | --- |
33
+ | `--framework hono` | Adds the router to the existing Hono entry, preserving its middleware and routes |
34
+ | `--framework honox` | Adds a config-driven route to `createApp()`, preserving its options, pages, and middleware |
35
+
36
+ Open `/slides/welcome`. Init chooses another sample name if an existing deck has
37
+ that slug. Existing MDX decks, components, and images remain supported.
38
+
39
+ Hono init detects a single `src/index.ts`, `.tsx`, `.js`, `.mts`, `.mjs`, or
40
+ `src/app.ts`, `.tsx`, `.js` candidate. Use `--entry src/server.ts` for a custom
41
+ entry or multiple candidates. Automatic connection supports a default-exported
42
+ `const app = new Hono()`. It leaves files unchanged and explains manual mounting
43
+ when earlier catch-all/dynamic routes or another app shape prevent a safe edit.
44
+
45
+ HonoX init supports the standard `app/routes` layout and a default-exported
46
+ `createApp()` call in `app/server.ts`. It creates `src/honox-decks.ts` and wraps
47
+ the existing createApp options. The helper adds the deck route through the public
48
+ HonoX `ROUTES` API, so **changing `mountPath` alone changes the public path**.
49
+ There is no route directory to create or rename. Conflicts with existing routes
50
+ are errors. A mount change during development automatically restarts Vite after
51
+ compilation so route registrations switch together.
52
+ The generated HonoX file owns only `import.meta.glob` route discovery and a
53
+ call to `withHonoXDecks()` from `hono-decks/honox`. Route composition and conflict
54
+ checks are supplied by the package, including dynamic and catch-all conflicts.
55
+ Package updates therefore update this behavior without regenerating app code.
56
+ Custom `createApp()` options, middleware, and explicit `ROUTES` are preserved.
57
+ Both modes accept `--config config/slides.ts`.
58
+
59
+ ## Void: use your existing dev and build commands
60
+
61
+ In an existing Void app, install hono-decks and a compatible Hono Markdown
62
+ adapter, then initialize once:
63
+
64
+ ~~~sh
65
+ npx hono-decks init --framework void --install
66
+ npm run dev
67
+ # Production build:
68
+ npm run build
69
+ ~~~
70
+
71
+ This integration requires `void-plugin-hono-jsx@^0.4.0` or a compatible adapter
72
+ with the `/markdown/compiler` and `/markdown/client` exports. `--install` selects
73
+ the supported adapter range. Without `--install`, also install the optional Markdown peers:
74
+ `markdown-exit@^1.3.0 yaml@^2.9.1 markdown-it-container@^4.0.0 shiki@^4.5.0 @shikijs/transformers@^4.5.0`.
75
+ The verified host versions are Void 1.1.11, Vite 8.3.4, and Hono 4.13.13.
76
+
77
+ `--install` selects npm/pnpm/Yarn/Bun from packageManager or lockfiles and installs
78
+ missing dependencies. Incompatible installed versions require an explicit update;
79
+ existing scripts are preserved. Yarn requires its node_modules linker; use manual
80
+ installation for PnP. Omit `--install` to manage dependencies yourself. To use a local adapter build, pass `--adapter /absolute/path/void-plugin-hono-jsx.tgz`.
81
+ Conflicting app files are checked before installation. Installation failures do not
82
+ write integration files; dependency and lockfile changes may remain.
83
+
84
+ `init --framework void` wraps the default export in the existing root
85
+ `vite.config.*` with `withHonoDecks()` and creates:
86
+
87
+ - `hono-decks.config.ts`: `/slides` mount, `decks` source directory, Hono Markdown enabled
88
+ - `src/decks.ts`: the app-owned facade
89
+ - `middleware/hono-decks.ts`: complete slide subtree routing, Markdown CSS, and dev reload support
90
+ - `decks/welcome/deck.md` and `Counter.tsx`: an interactive two-slide sample at `/slides/welcome`
91
+
92
+ If a `welcome` deck already exists, init chooses `welcome-2` (or the next free
93
+ name) and prints its URL, preserving the existing Markdown or MDX deck.
94
+
95
+ Edit the sample or add `.md` and `.mdx` decks under `decks`. Your existing Vite
96
+ `dev` and `build` commands perform compilation automatically, including from a
97
+ checkout without generated files. No manual `compile`, extra watch process, or
98
+ `package.json` script changes are needed. Generated code stays in memory, so no
99
+ generated directory or ignore entry is needed. Existing Void entry points, routes, and package scripts are preserved.
100
+ Choose a mount path that does not conflict with app routes; apply your app's
101
+ access policy to the slide subtree when needed.
102
+
103
+ The command checks dependencies and output conflicts before writing. It refuses
104
+ to overwrite integration files or add a second hono-decks integration. It accepts
105
+ ESM default-export config objects, expressions, and async config functions. For
106
+ an unsupported config, it leaves files unchanged and explains how to register
107
+ `honoDecks()` manually. `--config config/slides.ts` selects another config path;
108
+ `--out` and `--generated` apply only to the generic init below.
109
+
110
+ ## Client components inside Markdown
111
+
112
+ Island imports register their components automatically; no separate registry is needed.
113
+
114
+ ~~~md
115
+ <script>
116
+ import Counter from "./Counter.tsx" with { island: "load" };
117
+ </script>
118
+ ---
119
+ title: Interactive slide
120
+ ---
121
+ # Demo
122
+
123
+ <Counter label="Count" initial="2" />
124
+ ~~~
125
+
126
+ Counter.tsx exports a default Hono JSX component and can use useState from hono/jsx.
127
+ The initial HTML is rendered on the server. Hydration supports load, visible, idle,
128
+ and media:(query); visible scheduling waits for the slide to become active.
129
+ Imported CSS is compiled into deck styles, including SSR and print output.
130
+ useFrontmatter() and useMarkdownHeadings() provide each slide's context on both
131
+ server and client. Do not place secrets in metadata delivered to client islands.
132
+ Only relative default TSX/JSX imports and literal string/boolean props are supported.
133
+ JSX expressions, island tag children and arbitrary script code are unsupported.
134
+ Static imports and the existing MDX client-component workflow remain available.
135
+
136
+ ## Vite modules and typechecking
137
+
138
+ Hono + Vite, HonoX, and Void use the same `virtual:hono-decks` entry. Init creates
139
+ an app-owned `src/decks.ts` facade connected to it:
140
+
141
+ ~~~ts
142
+ /// <reference types="hono-decks/vite-env" />
143
+ import { decks } from "virtual:hono-decks";
144
+
145
+ export { decks };
146
+ ~~~
147
+
148
+ `decks` is configured with `hono-decks.config.ts`; its `router()`, `paths()`, and
149
+ other runtime APIs remain unchanged. The virtual module also exports
150
+ `createDecks(config)` when another configured kit is needed. Bundled ambient types
151
+ allow typechecking before the first dev or build run.
152
+
153
+ Edit sources, images, components, and themes under `decks/`, plus your config.
154
+ Vite reads compiled code from an in-memory module map and bundles it into the
155
+ application. There is no `src/generated` directory to create or import and no
156
+ need to set `build.outDir`. An explicitly configured OGP metadata cache is still
157
+ written to disk. Imported config inputs (for example a separate mount-path
158
+ settings file) are also watched. Init uses Vite's `BASE_URL` for its development
159
+ client script. If the host's dev server intercepts Vite URLs, keep its existing
160
+ asset exclusions configured for the chosen base.
161
+
162
+ Existing Vite facades that import their configured generated path also resolve
163
+ through the virtual graph, including `.js` imports that previously resolved to
164
+ generated TypeScript files. Prefer the stable entry above for new integrations.
165
+
166
+ The non-Vite CLI `hono-decks compile` and `compileDecks()` continue to write files
167
+ to `build.outDir` / `out`. Both destinations use the same compiler. Compiler and
168
+ Node filesystem code remain outside the application runtime.
169
+
170
+ ## Hono / MDX quick start
8
171
 
9
172
  The examples below use Bun. npm, pnpm, and Yarn are supported as well.
173
+ For a Vite-hosted Hono, HonoX, or Void app, use its init flow above instead of this manual compilation flow.
10
174
 
11
175
  ~~~bash
12
176
  bun add hono hono-decks
@@ -203,7 +367,7 @@ decks/product/
203
367
  index.tsx
204
368
  ~~~
205
369
 
206
- <code>components/index.tsx</code> contains server-side JSX components. <code>components/client/index.tsx</code> contains components hydrated in the browser. <code>theme.css</code> applies only to that deck. Local images are detected during compilation and rewritten to public URLs based on the mount path and deck slug.
370
+ <code>components/index.tsx</code> contains server-side JSX components. <code>components/client/index.tsx</code> contains components hydrated in the browser. <code>theme.css</code> applies only to that deck. Without a theme, slides use a white background and dark text. Customize `--hono-decks-background` and `--hono-decks-color` together in `theme.css`. Use `px` or `rem` within the fixed 1920 × 1080 canvas; viewport units change the composition when browser zoom changes. Local images are detected during compilation and rewritten to public URLs based on the mount path and deck slug.
207
371
 
208
372
  ## Embedding
209
373
 
@@ -249,7 +413,7 @@ export default defineDecksConfig({
249
413
 
250
414
  Override <code>imagePath</code> with a resolver when images are served from a separate CDN. Set Open Graph configuration to <code>false</code>, or omit it, to suppress social metadata.
251
415
 
252
- Image generation is intentionally not part of the core package. The <code>examples/ogp</code> recipe passes the manifest returned by <code>compileDecks()</code> from <code>hono-decks/node</code> to Satori and resvg, then stores 1200 by 630 PNG files in Workers Static Assets. Satori and resvg are example-only dependencies, and the recipe does not require Browser Rendering. Satori accepts TTF, OTF, and WOFF fonts but not WOFF2, so the build script must receive a font file that covers the target language.
416
+ Image generation is intentionally not part of the core package. The <code>examples/ogp</code> recipe uses the deck metadata returned by <code>compileDecks()</code> from <code>hono-decks/node</code> to Satori and resvg, then stores 1200 by 630 PNG files in Workers Static Assets. Satori and resvg are example-only dependencies, and the recipe does not require Browser Rendering. Satori accepts TTF, OTF, and WOFF fonts but not WOFF2, so the build script must receive a font file that covers the target language.
253
417
 
254
418
  <code>build.ogpCacheFile</code> stores external site metadata used by <code>@[card](...)</code>. It is separate from the viewer's share image.
255
419
 
@@ -259,6 +423,7 @@ Image generation is intentionally not part of the core package. The <code>exampl
259
423
  - <code>hono-decks/advanced</code>: <code>defineDecks()</code>, <code>decksRouter()</code>, <code>deckContext()</code>, raw renderers, and other low-level pipeline APIs
260
424
  - <code>hono-decks/client</code>: browser hydration
261
425
  - <code>hono-decks/node</code>: the compiler and Node filesystem adapter
426
+ - <code>hono-decks/honox</code>: shared HonoX route composition and conflict checks; no HonoX dependency is required by Hono-only apps
262
427
  - <code>hono-decks/vite</code>: Vite integration that compiles and watches decks during development
263
428
  - <code>hono-decks/cli</code>: the programmatic CLI runner
264
429
 
@@ -296,3 +461,32 @@ At this level, the application owns the mount path, source policy, and option me
296
461
  - <code>examples/minimal</code>: the smallest standalone Worker setup
297
462
  - <code>examples/basic</code>: R2, Browser Rendering, custom routes, and client components
298
463
  - <code>examples/honox</code>: HonoX integration
464
+
465
+ ## Void Hono Markdown
466
+
467
+ Set `build.markdown: "void"` in `hono-decks.config.ts` to opt into `.md` decks
468
+ alongside MDX. This requires `void-plugin-hono-jsx@^0.4.0` with its standalone compiler and client exports.
469
+ See the [Void consumer fixture](https://github.com/ts-76/hono-decks/tree/main/fixtures/void-markdown)
470
+ for package verification, Void middleware hosting, supported syntax and limitations.
471
+
472
+ ## Node build results and failure recovery
473
+
474
+ `compileDecks()` returns `CompileDecksResult`, containing `outDir`,
475
+ `routerModulePath` and deck build summaries. Each slide summary includes its
476
+ `modulePath` and metadata. This result is not a renderable `DeckManifest`.
477
+ Import `createDecks()` from the generated `decks.ts` for runtime routing.
478
+ Custom build scripts reading titles, warnings, assets or notes can continue
479
+ using `result.decks`; code passing the return value into `defineDecks()` must
480
+ switch to the generated module.
481
+
482
+ Synchronous renderers execute synchronous slide render functions and reject
483
+ async bodies with guidance to use the async renderer. Both renderers reject
484
+ build summaries without a renderable body instead of silently producing empty
485
+ slides.
486
+
487
+ The compiler completes slide generation, client bundling and OGP-cache
488
+ serialization before publishing. It stages all files and restores overwritten
489
+ files (including cache files) on a publication error. Application-owned files
490
+ are preserved. This guarantees rollback on reported build failure, not
491
+ crash-atomic publication or coordination between concurrent compiler processes.
492
+ If rollback itself fails, the error lists retained recovery directories.
@@ -177,6 +177,8 @@ interface CompiledDeck {
177
177
  meta: DeckFrontmatter;
178
178
  themeStyle?: string;
179
179
  themeSourcePath?: string;
180
+ /** Omit generated client code for explicitly static compiled decks. */
181
+ clientEntryRequired?: boolean;
180
182
  slides: CompiledSlide[];
181
183
  assets: AssetRef[];
182
184
  componentRegistry?: Record<string, SlideComponentInput>;
@@ -542,9 +544,11 @@ interface DefinedDecks<E extends Env = any> {
542
544
  }
543
545
  /** File-system settings consumed by the CLI. */
544
546
  interface DecksBuildConfig {
547
+ /** Opt into .md decks compiled by void-plugin-hono-jsx/markdown/compiler. */
548
+ markdown?: "void";
545
549
  /** Deck source directory. @default "decks" */
546
550
  root?: string;
547
- /** Generated module directory. @default "src/generated" */
551
+ /** CLI output directory. Vite keeps modules in memory. @default "src/generated" */
548
552
  outDir?: string;
549
553
  /** Optional deterministic Open Graph metadata cache. */
550
554
  ogpCacheFile?: string;