サンプル集(examples/)
fandhe-frontend フレームワークの動くサンプルは、リポジトリルート examples/ 配下に「正本」として置かれています。いずれも crates.io へ公開済みのクレートへのバージョン依存のみで完結する、独立した cargo プロジェクトです。本ページはサンプルの比較・読む順・fw new --example による取得手順をまとめます。
ssr-routing
Loader・respond_with・Router による SSR ページの構築。
ssg-blog
generate_pages による静的ブログ(sitemap.xml / robots.txt 付き)の書き出し。
dist-server-docker
単一バイナリ配布と Docker イメージでのデプロイ。
interactive-view-transitions
クライアント側状態管理と View Transitions の実演。
headless-pre-styled-ui
Primitives / Themes 2 層 UI コンポーネントのショーケース。
wireframe-ui
ローファイ・モノクロのワイヤーフレーム UI 全 49 部品のショーケース。
vercel-ssg
SSG から Vercel Build Output API を経由した静的配置。
vercel-ssr
Vercel Container Images(Beta)上でのリクエスト時 SSR。
1. 8 サンプルの比較
全サンプルに共通する前提は「Rust ツールチェーン(cargo)」「crates.io(https://index.crates.io / https://static.crates.io)への到達性」「fw gate --project examples/<name> を実行する場合の clippy component / cargo-deny(tools/ci/ensure-gate-tools.sh で導入)」の 3 点です。下表の「追加で必要なもの」はこの共通前提からの差分のみを示します。
| サンプル | 目的(何が作れるか) | 主要クレート | 追加で必要なもの | 所要目安 |
|---|---|---|---|---|
| ssr-routing | Loader・respond_with・Router による SSR ページの構築 | fandhe-frontend-core / -app / -server | なし | 短 |
| ssg-blog | generate_pages / generate_assets による静的サイト(ブログ + sitemap.xml / robots.txt)の書き出し | fandhe-frontend-core / -server | なし | 短 |
| dist-server-docker | 単一バイナリ配布・Docker イメージでのデプロイ | fandhe-frontend-dist-server | Docker(イメージのビルド・起動を試す場合) | 中 |
| interactive-view-transitions | クライアント側状態管理・View Transitions の実演 | fandhe-frontend-core / -app / -interactive(+ -wasm-full) | rustup target add wasm32-unknown-unknown と、wasm/Cargo.lock の解決版に一致する wasm-bindgen-cli(ブラウザでの実動作確認時のみ) | 長 |
| headless-pre-styled-ui | Primitives / Themes 2 層 UI コンポーネントのショーケース | fandhe-frontend-core / -pre-styled-ui(headless 層 API は再エクスポート経由) | なし | 短 |
| wireframe-ui | ローファイ・モノクロのワイヤーフレーム UI(Phase 1〜8・全 49 部品)のショーケース | fandhe-frontend-core / -wireframe-ui | なし | 短 |
| vercel-ssg | SSG → Vercel Build Output API → vercel deploy --prebuilt の静的配置 | fandhe-frontend-core / -server | Vercel CLI とアカウント(デプロイを試す場合のみ) | 短 |
| vercel-ssr | Vercel Container Images(Beta)上でのリクエスト時 SSR(PORT による bind 先解決・SIGTERM による graceful shutdown) | fandhe-frontend-dist-server | Docker(イメージのビルド・起動を試す場合)、Vercel CLI とアカウント・Container Images(Beta)の有効化(デプロイを試す場合のみ) | 中 |
「所要目安」は追加ツール導入の有無と手順ステップ数から算出した目安であり、実測値ではありません。
2. 読む順
Tip
どれから読むか迷う場合は ssr-routing から始めてください。
- Step 1(最初に読む): ssr-routing
Loader/respond_with/Routerと既定エスケープ(REQ-1)という、他の全サンプルが前提にする基本要素が揃っています。examples 規約の初例(#499)でもあり、structure.toml/clippy.toml/deny.tomlの共通構成もここで理解できます。 - Step 2(目的で分岐)
- 静的サイト(ブログ等)を作りたい → ssg-blog
- 単一バイナリ / Docker でデプロイしたい → dist-server-docker
- クライアント側の状態管理・ページ遷移アニメーションを試したい → interactive-view-transitions
- UI 部品(Primitives / Themes 2 層)を試したい → headless-pre-styled-ui
- ローファイ・モノクロのワイヤーフレーム UI(blocks.pm 相当)を試したい → wireframe-ui
- Vercel へ静的配置したい(推奨) → vercel-ssg
- Vercel 上でリクエスト時 SSR をしたい → vercel-ssr
- Step 3(応用)目的別ガイド(コンポーネント作成ガイド 等)と API Reference へ進んでください。
3. 各サンプルの詳細
3.1 ssr-routing
Loader trait の自作実装・respond_with による SSR 応答組み立て・Router によるパスパラメータ処理・既定エスケープ(REQ-1)を学べます。加えて el_owned / attr_if / attr_if_value(fandhe-frontend-core 0.2.0 以降、イシュー #1121)による条件付き属性の組み立ても実演します。el の Vec<(&str, &str)> は format!/to_string した動的な属性値と相性が悪く(借用元が呼び出し元スタックフレームより長生きする必要がある)、el_owned は属性を Vec<(String, String)> として直接受け取ることでこの制約を外します。attr_if/attr_if_value が返す Option<(String, String)> を chain/flatten で合成すると、条件不成立時は属性自体が出力から欠落します(hidden/disabled のような真偽属性の慣例に沿う設計)。実装例は src/main.rs の hello_response を参照してください。関連: API Reference。
3.2 ssg-blog
generate_pages による静的サイト書き出し・パス検証の fail-closed 契約・View Transitions の有効化を学べます。加えて generate_assets(fandhe-frontend-server 0.2.0 以降)による sitemap.xml / robots.txt の書き出しも実演します(イシュー #1135)。
generate_assets は generate_pages と異なり任意のファイル名を持つ非 HTML 生成物を書き出す汎用 API です。利用手順:
use fandhe_frontend_server::ssg::generate_assets;
use std::path::Path;
// (リクエストパス, コンテンツ文字列) の列を組み立てる。
let assets = vec![
("/sitemap.xml".to_string(), sitemap_xml),
("/robots.txt".to_string(), robots_txt),
];
// generate_pages と同じ fail-closed のパス検証を経由して dist/ へ書き出す。
generate_assets(&assets, Path::new("dist"))?;generate_assets を使う際は以下の 3 点に注意してください。
- fail-closed:
assets全件のパスを書き出し前に検証し、正規化後の重複も検出します。1 件でも不正・重複があれば 1 つも書き出さずにエラーを返します(generate_pagesと同型)。 - 既定エスケープ(REQ-1)は適用されない: コンテンツは無加工で書き出されます(
Node木・fandhe_frontend_core::renderを経由しません)。HTML ページの生成には使わずgenerate_pagesを使ってください。sitemap.xmlの URL 等、コンテンツ内部のエスケープ(XML エスケープ等)は呼び出し側の責務です。 fandhe-frontend-server0.2.0 以降が必要:generate_assetsはイシュー #1119 で追加された API です(0.1.x には含まれません)。
実装例は ssg-blog の src/main.rs(build_assets / main)を参照してください。
さらに fandhe_frontend_core::json_ld(fandhe-frontend-core 0.2.0 以降、イシュー #1117)による JSON-LD 構造化データの <script type="application/ld+json"> 埋め込みも実演します(記事一覧ページ(/)のみ、src/main.rs の website_json_ld / layout の head_extra 引数参照)。json_ld は既定エスケープ(REQ-1)の経路ではなく、シリアライズ済みの JSON 文字列を受け取って < > & 等の HTML 活性文字だけを \uXXXX 中立化する専用 API です。渡す文字列は既にシリアライズ済みの JSON である必要があり(serde_json::to_string の結果等)、HTML エスケープ済み文字列を渡すと JSON が壊れます。
3.3 dist-server-docker
単一バイナリ配布・FROM scratch の Docker イメージ最小化・外部依存利用時の静的アセット配信の制約と対処を学べます。本サンプルは fandhe-frontend-dist-server を crates.io からの外部依存として使うため build.rs の WASM ビルドステージが自動スキップされ、WASM は一切出荷されません。fandhe-frontend-wasm-full の「最小インタラクティブコンポーネント」7 feature 構成が実際に適用されるのは、fandhe-frontend-dist-server をワークスペース内でビルドする経路(例: ルート Dockerfile)に限られる点に注意してください。関連: wasm-full feature 選択ガイド。
3.4 interactive-view-transitions
Component trait による状態機械・dispatch/hydrate・start_router による SPA 内 View Transitions の自動有効化を学べます。wasm/Cargo.toml は default-features = false + fandhe-frontend-wasm-full の feature を実指定しており(イシュー #2525)、in-view / gesture / scroll-driver / layout FLIP / stagger の Phase 4 アニメーション配線(motion-demo-root セクション・item-list の opt-in 属性)も実演します。関連: Interactive API、wasm-full feature 選択ガイド、アニメーション機能ガイド。
3.5 headless-pre-styled-ui
Primitives 層(fandhe-frontend-headless-ui 相当、anatomy・data-*・WAI-ARIA 属性)と Themes 層(fandhe-frontend-pre-styled-ui、スタイル済み部品)の 2 層 UI コンポーネント構成(Tabs/Accordion/Dialog/Switch/ RadioGroup/Avatar 等)を学べます。加えて Theme::upsert_color / Theme::upsert_space(fandhe-frontend-pre-styled-ui 0.38.0 以降、イシュー #1138)によるテーマトークンの上書き・追加も実演します。push_color 等は同名トークンを DuplicateTokenName で fail-closed 拒否するため、Theme::default() の既定パレット(accent)を差し替える正規経路は upsert_color です(不在トークンに対しては push_color と同じ挿入動作になります)。実装例は src/main.rs の build_stylesheet を参照してください。関連: Pre-styled UI API。
3.6 wireframe-ui
fandhe-frontend-wireframe-ui(blocks.pm 参照のローファイ・モノクロワイヤーフレーム UI コンポーネント層。SSR 専用・非インタラクティブ)の全 49 部品を Phase 1〜8(レイアウト骨格 / テキスト・注釈 / Forms A / Forms B / Navigation / Overlay・Feedback / Data display / Media・データ表示)の区分どおりに 1 ページへ並べて実演します。headless-ui/pre-styled-ui とは独立した第 3 の UI 層であり、本サンプルも fandhe-frontend-app/-server に依存せず dist/index.html を直接組み立てて書き出す最小構成です。wireframe_css() の CSS は <style> へインライン埋め込みせず、dist/assets/wireframe.css へ書き出して <link rel="stylesheet"> で参照します(> を含む子結合子セレクタが既定エスケープにより > へ実体参照化されるのを避けるための設計判断。詳細は src/main.rs rustdoc「CSS の出力方式」節を参照)。実装例は src/sections.rs の Phase 別セクション関数を参照してください。関連: docs/design/wireframe-ui-architecture.md。
3.7 vercel-ssg
親トラッキング #3282 の Phase 1(#3284〜#3286、#3288)で確定した Vercel 上の静的配置の既定方式(SSG → Vercel Build Output API → vercel deploy --prebuilt、案 c)を学べます。vercel_runtime 1.x は起動時に panic し、2.x は依存グラフ上限(60 件/深さ 6)を超えるため不採用となった経緯は docs/design/vercel-deployment-strategy.md を参照してください。Vercel 上でリクエストごとの SSR が必要な場合は次の §3.8 vercel-ssr を参照してください。
generate_pages(HTML ページを Build Output API の static/ へ)と generate_assets(config.json・404.html の生成)を組み合わせ、「ファイルシステムに一致しなければ 404」を config.json の routes で表現する方法を実演します。生成前に固定リテラルの出力先(.vercel/output)だけを削除する fail-closed な取り扱い(vercel link が作る .vercel/project.json は削除しない)も含みます。実装例は src/main.rs の clean_output_dir / main を参照してください。Vercel の Deployment Protection(Vercel Authentication/SSO)に関する注意は vercel-ssg の README を参照してください。
3.8 vercel-ssr
決定記録 docs/design/vercel-deployment-strategy.md で SSR 用に §3.7 の案 c と並置採用された案 d(Vercel Container Images・Beta)の実演です。crates.io へ公開済みの fandhe-frontend-dist-server を通常の外部依存として使い、Vercel Container Images 上でリクエストごとの SSR を行います。
- bind 先アドレスの優先順位:
FANDHE_FRONTEND_BIND_ADDR>PORT(0.0.0.0:$PORT)> 既定127.0.0.1:3100。PORTが不正値なら fail-closed に起動失敗します SIGTERM/SIGINTを受けると listener を drop し、処理中の接続を最大 25 秒 drain してからexit 0しますDockerfile.vercelはFANDHE_FRONTEND_BIND_ADDRを設定しません。非 root 実行のため、Vercel プロジェクトのPORTは 1024 以上に設定する必要があります- 外部依存として利用するため、
examples/dist-server-dockerと同様に静的アセット(/static/*)と WASM は出荷しません - 静的出力で足りる場合は §3.7 vercel-ssg(案 c)を推奨します
- Vercel 実機での検証はまだ行っていません(イシュー #3339)
実装例・デプロイ手順の詳細は vercel-ssr の README を、Vercel での全体的な選び方は デプロイガイド を参照してください。
4. fw new --example での取得
各サンプルは fw CLI(fandhe-frontend-cli)の --example オプションで自分のプロジェクトとして展開できます。fw の導入手順は クイックスタート を参照してください。
cargo install fandhe-frontend-cli
fw new my-app --example ssr-routing--example に指定できるサンプル名は ssr-routing / ssg-blog / dist-server-docker / interactive-view-transitions / headless-pre-styled-ui / wireframe-ui / vercel-ssg / vercel-ssr の 8 種類です。展開されたプロジェクトはリポジトリの examples/ 配下と全ファイルバイト一致(パッケージ名の置換は行いません)で、そのまま cargo build / cargo test / fw gate --project . が通る状態です。
5. 共通規約
各サンプルは以下の構成に従います(詳細は examples/README.md を参照)。
- root workspace から独立した
[workspace] members = ["."](サンプル単体でcargo build/cargo testが完結する) structure.toml/clippy.toml/deny.tomlを同梱し、fw gate --project examples/<name>がそのまま通る- 既定エスケープ(REQ-1): ノード木 API のみで HTML を組み立て、
raw_html()やformat!による HTML 文字列の直接組み立てを行わない - README は「概要 / 学べること / 前提 / 動かし方 / 主要ファイル / 関連ガイド」の節構成
headless-pre-styled-ui は作成当初(イシュー #552)、依存する fandhe-frontend-headless-ui が crates.io 未公開だったため path 依存の意図的な例外でしたが、前提クレート公開(イシュー #608)を受けてイシュー #609 でバージョン依存へ切り替え、fw new --example にも対応済みです。
6. 次のステップ
- クイックスタート:
fw new --template appから始める入門ガイド - コンポーネント作成ガイド: ページ・コンポーネントの実装方法
- API Reference: 各 API の詳細仕様
- 迷ったら本ページの「2. 読む順」に戻り、ssr-routing から段階的に進めてください