Facade
Das Modul wippy/facade stellt eine portable Facade bereit, die das Wippy-Frontend von einem CDN lädt und konfiguriert. Es liefert eine schlanke HTML-Seite aus, die den JS-Modul-Einstiegspunkt des Web Host lädt (module.js für die standardmäßige Compat-Shell oder managed-layout.js für den Managed-Modus), die Authentifizierung übernimmt und die Konfiguration zwischen Backend und Frontend überbrückt. Das geladene Modul übernimmt die gesamte Seite und deren Browser-Verlauf.
Die iframe-basierte Auslieferung (iframe.html plus SetConfig-PostMessage-Handshake) bleibt für manuelle, Facade-lose Einbettungen verfügbar, bei denen du den Host selbst zur Isolation oder für Teilseiten einbettest; die Facade selbst nutzt sie jedoch nicht mehr.
Für isolierte oder teilweise Seitenintegrationen kann der Host weiterhin manuell über
iframe.html und einen SetConfig-Handshake per postMessage eingebettet werden. Die
Facade selbst verwendet diesen Auslieferungsmodus nicht.
Füge das Modul zu deinem Projekt hinzu:
wippy add wippy/facade
wippy install
Deklariere die Abhängigkeit:
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
Konfigurationsparameter
| Parameter | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
server |
ja | — | HTTP-Server für die Auslieferung statischer Dateien und Seiten |
router |
ja | — | Öffentlicher API-Router für den Config-Endpunkt |
fe_facade_url |
nein | https://web-host.wippy.ai/<release-tag> |
Basis-CDN-URL für das Frontend-Bundle |
fe_entry_path |
nein | /iframe.html |
Pfad zum iframe-Einstiegspunkt im Bundle, verwendet vom iframe-Einbettungsmodus. Die aktuelle Facade-Seite lädt stattdessen den JS-Modul-Einstiegspunkt (module.js/managed-layout.js); dieser iframe-Pfad bleibt für manuelle, Facade-lose iframe-Einbettungen verfügbar. |
fe_mode |
nein | compat |
Welche Shell die Facade-Seite lädt: compat lädt module.js (die standardmäßige Chat-Shell); managed lädt managed-layout.js (optionales deklaratives Multi-Panel-Layout). Wird auf /facade/config als mode/module_file bereitgestellt. |
host_config_layout |
nein | {} |
JSON-Layout-Konfiguration, die als hostConfig.layout ausgegeben wird; wird ausschließlich von der Managed-Shell konsumiert. |
render_engine |
nein | iframe |
Render-Engine der Seite, ausgegeben als hostConfig.renderEngine. Siehe Render-Engine. |
login_path |
nein | /login.html |
Pfad auf dem Origin der Seite, auf den nicht authentifizierte Benutzer weitergeleitet werden; funktioniert zusammen mit login_redirect_param. |
login_redirect_param |
nein | "" (aus) |
Name des Query-Parameters, an den beim Weiterleiten auf login_path die Rücksprung-URL nach dem Login angehängt wird. Leer deaktiviert das Anhängen der Rücksprung-URL. |
extra_scripts |
nein | [] |
JSON-Array zusätzlicher Skript-URLs, die die Facade-Seite lädt; wird auf /facade/config als extraScripts ausgegeben. |
Render-Engine
render_engine wählt die Seiten-Render-Engine für das gesamte Deployment. Sie wird als hostConfig.renderEngine ausgegeben und vom Web Host an seiner einzigen Verzweigung für das Seiten-Rendering gelesen.
| Wert | Wirkung |
|---|---|
iframe (Standard) |
Seiten werden als srcdoc-iframes gerendert — die primäre (Standard-)Engine. |
fragment |
Seiten werden als Web Fragments gerendert (ein reframed-Realm, gespiegelt in einen Shadow Root). |
Nur die exakte Zeichenfolge fragment aktiviert die Option; jeder andere Wert — einschließlich eines Tippfehlers wie fragmnet — wird auf iframe zurückgesetzt (ausfallsicher, aber ohne Meldung). Die Fragment-Engine benötigt zusätzlich das /@fragment-Gateway, das wippy/views (≥ 0.5.9) selbst bereitstellt — keine Verdrahtung auf Consumer-Seite. Eine Seite kann den Deployment-Standard pro Seite mit wippy.renderEngine überschreiben.
App-Identität
| Parameter | Standard | Beschreibung |
|---|---|---|
app_title |
Wippy |
In der Sidebar angezeigter Titel |
app_name |
Wippy AI |
Vollständiger Anwendungsname |
app_icon |
wippy:logo |
Iconify-Icon-Referenz |
Feature-Flags
| Parameter | Standard | Beschreibung |
|---|---|---|
hide_nav_bar |
false |
Linke Navigations-Sidebar ausblenden |
disable_right_panel |
false |
Rechtes Sidebar-Panel deaktivieren |
start_nav_open |
false |
Navigationsschublade standardmäßig geöffnet |
show_admin |
true |
Umschalter für das Admin-Panel anzeigen |
allow_select_model |
false |
Benutzer darf das LLM-Modell auswählen |
session_type |
non-persistent |
Speicherung des Auth-Tokens: non-persistent (im Arbeitsspeicher) oder cookie. Der Web Host behandelt jeden anderen Wert als cookie wie non-persistent. |
history_mode |
hash |
Browser-Verlaufsmodus: hash oder browser. Der Web Host behandelt jeden anderen Wert als browser wie hash. |
hide_session_selector |
false |
Sitzungsauswahl-UI ausblenden |
Theming
Drei Bereiche gelten: global (überall), host (das Chrome des Web Host — Sidebar, Chat, Seitenbereich) und children (sowohl untergeordnete view.page-iframes als auch view.component-Web-Components). Welche Oberfläche jeder Schalter erreicht, zeigt die CSS-Delivery-Matrix.
| Parameter | Bereich | Standard | Beschreibung |
|---|---|---|---|
custom_css |
global | Google Fonts Import | Globales CSS — erreicht Host-Chrome, view.page-iframes und view.component-Shadow-Roots (1.0.43+). |
css_variables |
global | {} |
JSON-Map beliebiger CSS-Custom-Properties; wird für Auto- und erzwungene Modi kompiliert und in Komponenten-Shadow-Roots übertragen. |
icon_sets |
global | [] |
Iconify-Icon-Set-URLs (nur inline als JSON — kein fs://) |
host_custom_css |
host | "" |
CSS nur für das Host-Chrome — nicht für Children. Klassenbasierte Regeln auf .wippy-host-app einschränken. |
host_css_variables |
host | {} |
CSS-Custom-Properties nur für das Host-Chrome |
host_icon_sets |
host | [] |
Icon-Sets nur für den Host (nur inline als JSON) |
children_custom_css |
children | "" |
CSS nur für Children — wird in view.page-iframes und view.component-Shadow-Roots (1.0.43+) injiziert, nicht in das Host-Chrome |
children_css_variables |
children | {} |
CSS-Custom-Properties nur für Children |
Standardempfehlung: Lege gemeinsames Styling und Branding in custom_css und css_variables (global) ab — dort gehören etwa 95 % des Themings hin, und es erreicht jede Oberfläche. Reserviere host_custom_css / host_css_variables für Host-eigenes Chrome (Sidebar, Chat-Panel, Splitter). Eine view.component deaktiviert *_custom_css im Shadow Root mit customCss: false.
Theme-Modus und Persistenz
| Parameter | Standard | Beschreibung |
|---|---|---|
theme_mode |
auto |
Erzwungenes Theme für Host und Children: auto (folgt dem Betriebssystem), light oder dark. Wird auf /facade/config als themeMode ausgegeben. |
theme_persist |
none |
Das vom Benutzer gewählte Theme über Reloads hinweg speichern: none, cookie oder localStorage. Im cookie-Modus liest die per Jet gerenderte Shell das Cookie serverseitig und wendet die w-theme-*-Klasse vor dem ersten Paint an (kein Flackern). Wird als themePersist ausgegeben. |
theme_storage_key |
@wippy-theme-mode |
Cookie- bzw. localStorage-Schlüssel, unter dem der Modus gespeichert wird. Wird als themeStorageKey ausgegeben und in das generierte /facade/theme-persist.js eingebettet. |
Theme-Persistenz ist opt-in: theme_persist steht standardmäßig auf none, es wird also nichts gespeichert, bis ein Deployment den Wert auf cookie oder localStorage setzt. Ist sie aktiviert, liefert die Facade unter GET /facade/theme-persist.js ein fertiges Skript mit eingebettetem Schlüssel und Modus aus; binde es auf jeder Seite ein, die das Theme teilen soll. Das vollständige Modell, das Host-Event themeChanged und die Integration von Nicht-Wippy-Seiten beschreibt Theme-Persistenz.
Facade-Theming auf Seiten außerhalb des Web Host wiederverwenden
Eine Seite, die außerhalb des Web Host ausgeliefert wird — deine login.html, eine Fehlerseite, eine E-Mail-Bestätigungsseite — kann dasselbe Facade-Brand-Theme wiederverwenden, statt es zu duplizieren, sodass deine Tokens und eigenen Regeln an einer Stelle liegen.
Halte custom_css und css_variables zunächst in eigenständigen Dateien statt sie inline zu schreiben, und verweise die Parameter mit fs:// plus einem content_fs-Dateisystem auf diese Dateien:
custom_css: fs://custom-css.facade.css
css_variables: fs://css-variables.facade.json
content_fs: app:app_fs
Verwende fs:// (zur Laufzeit von content_fs aufgelöst), nicht file:// — file:// wird vom wippy-Loader beim Laden relativ zur YAML-Datei inline eingefügt. Lege die Dateien in denselben statischen Ordner, aus dem auch deine login_path-Seite ausgeliefert wird (in app wird static/ unter /app bereitgestellt).
Die fs://-Auflösung gilt für genau sechs Theming-Parameter — custom_css, css_variables, host_custom_css, host_css_variables, children_custom_css, children_css_variables (CSS-Strings werden wörtlich gelesen; JSON-Dateien für *_css_variables werden als Variablen-Map geparst). icon_sets / host_icon_sets und jeder andere JSON-Parameter (api_routes, chat, tanstack, …) sind ausschließlich inline; fs:// wird dort nicht aufgelöst.
Eine eigenständige Seite bindet dann beides ein:
custom_css— bereits eine.css-Datei und daher direkt von ihrem Auslieferungsort verlinkbar.css_variables— JSON und damit nicht direkt verlinkbar. Die Facade rendert die Datei unterGET /facade/variables.cssals Basis plus effektive Blöcke für Auto-Light, Auto-Dark, erzwungenes Light und erzwungenes Dark. Werte auf oberster Ebene gelten überall;@light/@darkersetzen ausgewählte Namen. Das Stylesheet wird 1 Stunde gecacht und auf demselben öffentlichen Router registriert wie/facade/config, trägt also dessen Router-Prefix.
<!-- in login.html, ausgeliefert außerhalb des Web Host -->
<link rel="stylesheet" href="/api/public/facade/variables.css"> <!-- css_variables, generiertes CSS -->
<link rel="stylesheet" href="/app/custom-css.facade.css"> <!-- custom_css-Datei -->
Um auch den Theme-Modus zu teilen (sodass eine login.html dieselbe Hell/Dunkel-Wahl wie der Host respektiert und speichert), binde das generierte Theme-Persist-Skript ein und rufe dessen write() aus deinem Umschalter auf:
<script src="/api/public/facade/theme-persist.js"></script>
<!-- wendet das gespeicherte Theme früh an und stellt window.wippyThemePersist bereit -->
Ein vollständiges Umschalter-Beispiel findest du unter Theme-Persistenz → Nicht von Wippy gehostete Seiten.
Optionale JSON-Parameter
Jeder der folgenden Parameter ist ein JSON-kodierter String; Standardwerte sind leer ({} oder []).
Diese vier werden unverändert unter hostConfig für das Frontend bereitgestellt:
| Parameter | Standard | Beschreibung |
|---|---|---|
additional_nav_items |
[] |
Zusätzliche Sidebar-Einträge |
state_cache |
{} |
Konfiguration des Frontend-State-Caches |
allow_additional_tags |
{} |
Tag-Whitelist des HTML-Sanitizers (Record<string, string[]>, Tag → erlaubte Attribute) |
chat |
{} |
Chat-UI-Überschreibungen |
Diese drei werden als oberste AppConfig-Felder ausgegeben (Geschwister von hostConfig), nicht unterhalb von hostConfig:
| Parameter | Ausgegeben als | Standard | Beschreibung |
|---|---|---|---|
api_routes |
apiRoutes |
{} |
Routen-Überschreibungen für das Frontend |
axios_defaults |
axiosDefaults |
{} |
Standardwerte des Frontend-Axios-HTTP-Clients |
tanstack |
tanstack |
{} |
TanStack-Query-Standardwerte: { default?, content?, lists? }. default gilt für alle Queries; content zielt auf Renderings einzelner Ressourcen, lists auf Navigations- und Index-Queries. Host-Standard ist refetchOnWindowFocus:false |
Diese drei Werte werden als Felder der obersten Ebene von AppConfig ausgegeben,
nicht unter hostConfig:
Die Facade registriert GET /facade/config auf dem konfigurierten Router. Dieser Pfad wird auf dem öffentlichen Router registriert, daher enthält die URL, die die Seite tatsächlich abruft, das Prefix des Routers — mit dem Beispiel-Prefix /api/public (siehe Setup) lautet sie /api/public/facade/config, und genau das ruft die mitgelieferte Facade-Seite ab. (Die Facade registriert eine weitere Route auf demselben Router — GET /facade/variables.css, die css_variables gerendert als text/css-Stylesheet für Seiten außerhalb des Web Host; siehe Facade-Theming auf Seiten außerhalb des Web Host wiederverwenden.) Das Frontend ruft die Konfiguration beim Laden ab:
{
"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": { "...": "..." }
}
}
Die API-URL wird aus der Umgebungsvariable PUBLIC_API_URL gelesen; APP_WEBSOCKET_URL wird durch Ersetzen von http:// mit ws:// oder https:// mit wss:// abgeleitet. Theming hat drei Bereiche (global, host, children) — host.i18n enthält das App-Branding. hostConfig-Schlüssel sind in camelCase und werden aus Facade-Parametern zusammengesetzt: session_type, history_mode, render_engine, show_admin, allow_select_model, start_nav_open, hide_nav_bar, disable_right_panel, hide_session_selector, plus optional additional_nav_items, state_cache, allow_additional_tags und chat. Aus render_engine wird renderEngine (siehe Render-Engine). Die Parameter api_routes, axios_defaults und tanstack werden als oberste AppConfig-Felder (apiRoutes, axiosDefaults, tanstack) ausgegeben, als Geschwister von hostConfig und nicht darin.
Die Felder facade_url, iframe_origin, iframe_url, login_path, mode und module_file sind Shell-Ebene-Felder, mit denen sich die einbettende Seite selbst aufbaut — sie gehören nicht zur untergeordneten AppConfig, mit der sich der Host initialisiert. Die Felder iframe_origin/iframe_url werden ausschließlich von manuellen, Facade-losen iframe-Einbettungen konsumiert (siehe Facade-Einstiegspunkt). Das Feld mode ist das normalisierte fe_mode (compat oder managed), und module_file ist der JS-Modul-Einstiegspunkt, den die Facade-Seite lädt — /module.js für compat, /managed-layout.js für managed.
Die API-URL stammt aus PUBLIC_API_URL; APP_WEBSOCKET_URL wird durch Ersetzen von
http:// durch ws:// beziehungsweise https:// durch wss:// abgeleitet.
hostConfig verwendet camelCase und enthält die Facade-Parameter einschließlich
render_engine als renderEngine (siehe Render-Engine). api_routes, axios_defaults und tanstack
werden als gleichrangige Top-Level-Felder apiRoutes, axiosDefaults und tanstack
ausgegeben.
Über wippy/views registrierte Seiten erscheinen anhand ihrer Metadaten automatisch in der Sidebar:
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/
Sidebar-Gruppen
Seiten mit demselben group-Wert werden zu einklappbaren Abschnitten zusammengefasst. Gruppen werden nach group_order sortiert (niedriger zuerst), Seiten innerhalb einer Gruppe nach order.
| Feld | Beschreibung |
|---|---|
group |
In der Sidebar angezeigter Kategoriename |
group_icon |
Icon für die Kategorie-Überschrift |
group_order |
Sortierposition der Gruppe (niedriger = weiter oben) |
group_placement |
"sidebar" (in der Sidebar) oder "default" (nur im Hauptbereich) |
Seiten ohne group erscheinen als Einträge auf oberster Ebene.
Sichtbarkeit steuern
| Feld | Wirkung |
|---|---|
announced: true |
Seite erscheint in der Sidebar-Navigation |
announced: false |
Seite ist in der Navigation ausgeblendet, aber weiterhin über die URL erreichbar |
inline: true |
Interne Seite, in allen UI-Listen ausgeblendet |
hide_nav_bar: true |
Facade-Parameter — blendet die gesamte linke Sidebar aus |
Veröffentlichen mit eingebetteten Assets
Wenn du eine Komponente veröffentlichst, die statische Dateien enthält (etwa das public/-Verzeichnis der Facade), nutze --embed, um fs.directory-Einträge in das Paket aufzunehmen:
wippy publish --embed facade:public_files
Ohne --embed werden fs.directory-Einträge aus dem veröffentlichten Paket ausgeschlossen. Das Flag --embed akzeptiert Entry-IDs oder Namen, die zu fs.directory-Einträgen passen.
Siehe auch
- Views - Seiten- und Komponentensystem
- HTTP-Server - Konfiguration des HTTP-Dienstes
- Framework-Überblick - Verwendung der Framework-Module
- Facade-Einstiegspunkt - Wie die Facade den Web Host bootstrappt (FE-Perspektive)
- CSS-Injection - Wie Facade-Theming in untergeordnete iframes fließt
- Render-Engines - Iframe- vs. Web-Fragment-Seitenrendering (der
render_engine-Schalter)