Facade
wippy/facadeモジュールは、CDNからWippyフロントエンドを読み込んで設定する可搬なファサードを提供します。Web HostのJSモジュールエントリ(デフォルトのcompatシェルではmodule.js、managedモードではmanaged-layout.js)を読み込む薄いHTMLページを配信し、認証を処理し、バックエンドとフロントエンドの間で設定を橋渡しします。読み込まれたモジュールはページ全体とそのブラウザ履歴を引き継ぎます。
iframeベースの配信(iframe.htmlとSetConfig PostMessageハンドシェイク)は、分離や部分的なページ利用のために自分でホストを埋め込む手動のファサードなし埋め込み向けに引き続き利用できますが、ファサード自体はもう使用しません。
セットアップ
モジュールをプロジェクトに追加します:
wippy add wippy/facade
wippy install
依存関係を宣言します:
version: "1.0"
namespace: app
entries:
- name: gateway
kind: http.service
addr: :8090
lifecycle:
auto_start: true
- name: api
kind: http.router
meta:
server: app:gateway
prefix: /api/public
- name: dep.facade
kind: ns.dependency
component: wippy/facade
version: "*"
parameters:
- name: server
value: app:gateway
- name: router
value: app:api
設定パラメータ
| パラメータ | 必須 | デフォルト | 説明 |
|---|---|---|---|
server |
はい | — | 静的ファイルとページ配信用のHTTPサーバー |
router |
はい | — | configエンドポイント用の公開APIルーター |
fe_facade_url |
いいえ | https://web-host.wippy.ai/<release-tag> |
フロントエンドバンドルのベースCDN URL |
fe_entry_path |
いいえ | /iframe.html |
バンドル上のiframeエントリへのパス。iframe埋め込みモードで使用されます。現在のファサードのページは代わりにJSモジュールエントリ(module.js/managed-layout.js)を読み込みます。このiframeパスは、手動のファサードなしiframe埋め込み向けに引き続き利用できます。 |
fe_mode |
いいえ | compat |
ファサードページが読み込むシェル: compatはmodule.js(デフォルトのチャットシェル)、managedはmanaged-layout.js(オプトインの宣言的マルチパネルレイアウト)を読み込みます。/facade/configではmode/module_fileとして公開されます。 |
host_config_layout |
いいえ | {} |
hostConfig.layoutとして出力されるJSONレイアウト設定。managedシェルのみが利用します。 |
render_engine |
いいえ | iframe |
ページのレンダーエンジン。hostConfig.renderEngineとして出力されます。レンダーエンジンを参照してください。 |
login_path |
いいえ | /login.html |
未認証ユーザーのリダイレクト先となる、ページのオリジン上のパス。login_redirect_paramと組み合わせて動作します。 |
login_redirect_param |
いいえ | ""(無効) |
login_pathへリダイレクトする際に、ログイン後の戻り先URLを付加するクエリパラメータ名。空の場合は戻り先URLの付加が無効になります。 |
extra_scripts |
いいえ | [] |
ファサードページが読み込む追加スクリプトURLのJSON配列。/facade/configではextraScriptsとして出力されます。 |
レンダーエンジン
render_engineは、デプロイメント全体のページレンダーエンジンを選択します。hostConfig.renderEngineとして出力され、Web Hostが唯一のページレンダー分岐で読み取ります。
| 値 | 効果 |
|---|---|
iframe (デフォルト) |
ページはsrcdoc iframeとしてレンダリングされます — メイン(デフォルト)のエンジンです。 |
fragment |
ページはWeb Fragment(shadow rootに反映されるreframedレルム)としてレンダリングされます。 |
オプトインできるのは正確な文字列fragmentのみです。それ以外の値は — fragmnetのようなタイプミスを含めて — iframeにクランプされます(フェイルセーフですが、警告は出ません)。fragmentエンジンを有効にするには/@fragmentゲートウェイも必要ですが、これはwippy/views(0.5.9以上)が自ら提供するため、利用側での配線は不要です。ページはwippy.renderEngineでデプロイメントのデフォルトをページ単位に上書きできます。
アプリのアイデンティティ
| パラメータ | デフォルト | 説明 |
|---|---|---|
app_title |
Wippy |
サイドバーに表示されるタイトル |
app_name |
Wippy AI |
アプリケーションの正式名称 |
app_icon |
wippy:logo |
Iconifyアイコン参照 |
機能フラグ
| パラメータ | デフォルト | 説明 |
|---|---|---|
hide_nav_bar |
false |
左側のナビゲーションサイドバーを非表示にする |
disable_right_panel |
false |
右側のサイドバーパネルを無効にする |
start_nav_open |
false |
ナビゲーションドロワーをデフォルトで開いた状態にする |
show_admin |
true |
管理パネルの切り替えを表示する |
allow_select_model |
false |
ユーザーにLLMモデルの選択を許可する |
session_type |
non-persistent |
認証トークンの保存方法: non-persistent(メモリ内)またはcookie。Web Hostはcookie以外の値をすべてnon-persistentとして扱います。 |
history_mode |
hash |
ブラウザ履歴モード: hashまたはbrowser。Web Hostはbrowser以外の値をすべてhashとして扱います。 |
hide_session_selector |
false |
セッション選択UIを非表示にする |
テーミング
3つのスコープが適用されます: global(あらゆる場所)、host(Web Hostのクローム — サイドバー、チャット、ページ領域)、children(子のview.page iframeとview.componentウェブコンポーネントの両方)。各ノブがどのサーフェスに届くかは、CSS配信マトリクスを参照してください。
| パラメータ | スコープ | デフォルト | 説明 |
|---|---|---|---|
custom_css |
global | Google Fontsのimport | グローバルCSS — hostのクローム、view.page iframe、view.componentのshadow rootに届きます(1.0.43以降)。 |
css_variables |
global | {} |
任意のCSSカスタムプロパティのJSONマップ。Autoモードと強制モードの両方向けにコンパイルされ、コンポーネントのshadow rootにもブリッジされます。 |
icon_sets |
global | [] |
IconifyアイコンセットのURL(インラインJSONのみ — fs://は不可) |
host_custom_css |
host | "" |
hostのクローム専用のCSS — 子には届きません。クラスベースのルールは.wippy-host-appにスコープしてください。 |
host_css_variables |
host | {} |
hostのクローム専用のCSSカスタムプロパティ |
host_icon_sets |
host | [] |
host専用のアイコンセット(インラインJSONのみ) |
children_custom_css |
children | "" |
子専用のCSS — view.page iframeとview.componentのshadow rootに注入され(1.0.43以降)、hostのクロームには注入されません |
children_css_variables |
children | {} |
子専用のCSSカスタムプロパティ |
デフォルトの指針: 共有・ブランドのスタイリングはcustom_cssとcss_variables(global)に置いてください — テーミングの約95%はここに属し、あらゆるサーフェスに届きます。host_custom_css / host_css_variablesはhost専用のクローム(サイドバー、チャットパネル、スプリッター)のために取っておきます。view.componentはcustomCss: falseでshadow rootへの*_custom_cssをオプトアウトできます。
テーマモードと永続化
| パラメータ | デフォルト | 説明 |
|---|---|---|
theme_mode |
auto |
hostと子に対する強制テーマ: auto(OSに追従)、light、dark。/facade/configではthemeModeとして出力されます。 |
theme_persist |
none |
ユーザーが選んだテーマをリロード後も保持する: none、cookie、localStorage。cookieモードでは、Jetでレンダリングされるシェルがサーバー側でCookieを読み取り、初回描画の前にw-theme-*クラスを適用します(ちらつきなし)。themePersistとして出力されます。 |
theme_storage_key |
@wippy-theme-mode |
モードを保存するCookie / localStorageのキー。themeStorageKeyとして出力され、生成される/facade/theme-persist.jsに埋め込まれます。 |
テーマの永続化はオプトインです。theme_persistのデフォルトはnoneなので、デプロイメントがcookieまたはlocalStorageに設定するまで何も保存されません。有効にすると、ファサードはキーとモードを埋め込んだ既製のスクリプトを**GET /facade/theme-persist.js**で配信します。テーマを共有したいページに読み込んでください。完全なモデル、themeChanged hostイベント、Wippy以外のページとの統合についてはテーマの永続化を参照してください。
Web Host外のページでファサードのテーミングを再利用する
Web Hostの外で配信されるページ — login.html、エラーページ、メール確認ページなど — は、テーミングを複製する代わりに同じファサードのブランドテーマを再利用できるため、トークンやカスタムルールを一箇所にまとめられます。
まず、custom_cssとcss_variablesをインライン化せずスタンドアロンのファイルに保持し、fs://とcontent_fsファイルシステムでパラメータからそれらのファイルを指すようにします:
custom_css: fs://custom-css.facade.css
css_variables: fs://css-variables.facade.json
content_fs: app:app_fs
file://ではなくfs://(実行時にcontent_fsが解決)を使用してください — file://は読み込み時にwippyローダーがYAMLからの相対パスでインライン化します。ファイルはlogin_pathのページが配信されるのと同じ静的フォルダに置いてください(appでは/appで配信されるstatic/)。
fs://の解決が適用されるのは、ちょうど6つのテーミングパラメータ — custom_css、css_variables、host_custom_css、host_css_variables、children_custom_css、children_css_variables — のみです(CSS文字列はそのまま読み込まれ、JSONの*_css_variablesファイルは変数マップとしてパースされます)。icon_sets / host_icon_setsとその他すべてのJSONパラメータ(api_routes、chat、tanstackなど)はインライン専用で、そこではfs://は解決されません。
スタンドアロンのページは次の両方をリンクします:
custom_css— すでに.cssファイルなので、配信元から直接リンクできます。css_variables— JSONなのでそのままではリンクできません。ファサードは**GET /facade/variables.css**でこれをレンダリングし、baseに加えて実効のAutoライト、Autoダーク、強制ライト、強制ダークの各ブロックを出力します。トップレベルの値はあらゆる場所に適用され、@light/@darkが選択した名前を置き換えます。このスタイルシートは1時間キャッシュされ、/facade/configと同じ公開ルーターに登録されるため、ルーターのプレフィックスが付きます。
<!-- Web Hostの外で配信されるlogin.html内 -->
<link rel="stylesheet" href="/api/public/facade/variables.css"> <!-- css_variables、生成されたCSS -->
<link rel="stylesheet" href="/app/custom-css.facade.css"> <!-- custom_cssのファイル -->
テーマモードも共有する場合(login.htmlがhostと同じライト/ダークの選択を尊重して保持するように)、生成されたtheme-persistスクリプトを追加し、切り替えUIからそのwrite()を呼び出します:
<script src="/api/public/facade/theme-persist.js"></script>
<!-- 保存されたテーマを早期に適用し、window.wippyThemePersistを公開します -->
完全な切り替えUIの例はテーマの永続化 → Wippy外でホストされるページを参照してください。
オプションのJSONパラメータ
以下の各パラメータはJSONエンコードされた文字列です。デフォルトは空({}または[])です。
次の4つはhostConfig配下にそのままフロントエンドへ公開されます:
| パラメータ | デフォルト | 説明 |
|---|---|---|
additional_nav_items |
[] |
追加のサイドバー項目 |
state_cache |
{} |
フロントエンドの状態キャッシュ設定 |
allow_additional_tags |
{} |
HTMLサニタイザーのタグホワイトリスト(Record<string, string[]>、タグ → 許可される属性) |
chat |
{} |
チャットUIのオーバーライド |
次の3つはhostConfig配下ではなく、トップレベルのAppConfigフィールド(hostConfigの兄弟)として出力されます:
| パラメータ | 出力名 | デフォルト | 説明 |
|---|---|---|---|
api_routes |
apiRoutes |
{} |
フロントエンドのルートオーバーライド |
axios_defaults |
axiosDefaults |
{} |
フロントエンドaxios HTTPクライアントのデフォルト |
tanstack |
tanstack |
{} |
TanStack Queryのデフォルト: { default?, content?, lists? }。defaultはすべてのクエリに適用され、contentは単一リソースのレンダリング、listsはナビゲーション/インデックスのクエリを対象とします。hostのデフォルトはrefetchOnWindowFocus:falseです |
Configエンドポイント
ファサードは設定されたルーターにGET /facade/configを登録します。このパスは公開ルーター上に登録されるため、ページが実際にフェッチするURLにはルーターのプレフィックスが含まれます — 例のプレフィックス/api/public(Setupを参照)では/api/public/facade/configとなり、これは同梱のファサードページがフェッチするパスとまったく同じです。(ファサードは同じルーターにもう1つのルート — GET /facade/variables.css、Web Host外のページ向けにcss_variablesをtext/cssスタイルシートとしてレンダリングしたもの — を登録します。Web Host外のページでファサードのテーミングを再利用するを参照してください。)フロントエンドは読み込み時にこの設定をフェッチします:
{
"facade_url": "https://web-host.wippy.ai/<release-tag>",
"iframe_origin": "https://web-host.wippy.ai",
"iframe_url": "https://web-host.wippy.ai/<release-tag>/iframe.html?waitForCustomConfig",
"login_path": "/login.html",
"login_redirect_param": null,
"mode": "compat",
"module_file": "/module.js",
"extraScripts": null,
"env": {
"APP_API_URL": "https://api.example.com",
"APP_AUTH_API_URL": "https://api.example.com",
"APP_WEBSOCKET_URL": "wss://api.example.com"
},
"routePrefix": "https://api.example.com",
"apiRoutes": { "...": "..." },
"axiosDefaults": { "...": "..." },
"tanstack": { "lists": { "refetchOnWindowFocus": true } },
"theming": {
"global": { "customCSS": "...", "cssVariables": {}, "iconSets": {} },
"host": { "customCSS": "...", "cssVariables": {}, "iconSets": {}, "i18n": { "app": { "title": "Wippy", "icon": "wippy:logo", "appName": "Wippy AI" } } },
"children": { "customCSS": "...", "cssVariables": {} }
},
"hostConfig": {
"session": { "type": "non-persistent" },
"history": "hash",
"renderEngine": "iframe",
"showAdmin": true,
"allowSelectModel": false,
"startNavOpen": false,
"hideNavBar": false,
"disableRightPanel": false,
"hideSessionSelector": false,
"additionalNavItems": [],
"stateCache": { "...": "..." },
"allowAdditionalTags": { "w-chart": ["data", "type"] },
"chat": { "...": "..." }
}
}
API URLはPUBLIC_API_URL環境変数から読み取られます。APP_WEBSOCKET_URLはhttp://をws://に、またはhttps://をwss://に置き換えて導出されます。テーミングには3つのスコープ(global、host、children)があります — host.i18nにはアプリのブランディングが含まれます。hostConfigキーはcamelCaseで、facadeパラメータから組み立てられます: session_type、history_mode、render_engine、show_admin、allow_select_model、start_nav_open、hide_nav_bar、disable_right_panel、hide_session_selector、加えてオプションのadditional_nav_items、state_cache、allow_additional_tags、chat。render_engineはrenderEngineになります(レンダーエンジンを参照)。api_routes、axios_defaults、tanstackパラメータは、hostConfigの内側ではなくその兄弟となるトップレベルのAppConfigフィールド(apiRoutes、axiosDefaults、tanstack)として出力されます。
facade_url、iframe_origin、iframe_url、login_path、mode、module_fileの各フィールドは、埋め込みページが自身を構築するために使うシェルレベルのフィールドであり、hostが初期化に使う子のAppConfigの一部ではありません。iframe_origin/iframe_urlフィールドは、手動のファサードなしiframe埋め込みでのみ利用されます(Facadeエントリポイントを参照)。modeフィールドは正規化されたfe_mode(compatまたはmanaged)で、module_fileはファサードページが読み込むJSモジュールエントリです — compatでは/module.js、managedでは/managed-layout.jsです。
ナビゲーションサイドバー
wippy/views経由で登録されたページは、そのメタデータに基づいて自動的にサイドバーに表示されます:
entries:
- name: dashboard
kind: registry.entry
meta:
type: view.page
name: dashboard
title: Dashboard
icon: tabler:chart-bar
group: Analytics
group_icon: tabler:chart-dots
group_order: 10
order: 1
announced: true
secure: true
url: https://cdn.example.com/dashboard/
サイドバーのグループ
同じgroup値を持つページは、折りたたみ可能なセクションにまとめられます。グループはgroup_order(小さい順)、グループ内のページはorderでソートされます。
| フィールド | 説明 |
|---|---|
group |
サイドバーに表示されるカテゴリ名 |
group_icon |
カテゴリヘッダーのアイコン |
group_order |
グループの並び順(小さいほど上) |
group_placement |
"sidebar"(サイドバー内)または"default"(メイン領域のみ) |
groupを持たないページはトップレベルの項目として表示されます。
表示の制御
| フィールド | 効果 |
|---|---|
announced: true |
ページがサイドバーのナビゲーションに表示される |
announced: false |
ページはナビゲーションから隠されるが、URLからは引き続きアクセス可能 |
inline: true |
内部ページ。すべてのUI一覧から隠される |
hide_nav_bar: true |
ファサードのパラメータ — 左サイドバー全体を非表示にする |
埋め込みアセットを含む公開
静的ファイル(ファサードのpublic/ディレクトリなど)を含むコンポーネントを公開する際は、--embedを使ってパッケージにfs.directoryエントリを含めます:
wippy publish --embed facade:public_files
--embedがない場合、fs.directoryエントリは公開パッケージから除外されます。--embedフラグは、fs.directoryエントリに一致するエントリIDまたは名前を受け付けます。
関連項目
- Views - ページとコンポーネントのシステム
- HTTPサーバー - HTTPサービスの設定
- Framework概要 - Frameworkモジュールの使い方
- Facadeエントリポイント - ファサードがWeb Hostをブートストラップする仕組み(FE視点)
- CSSインジェクション - ファサードのテーミングが子iframeへ流れる仕組み
- レンダーエンジン - iframe対Web Fragmentのページレンダリング(
render_engineスイッチ)