# Bootstrap Sequence _Path: en/frontend/web-host/bootstrap_ ## Table of Contents - Bootstrap Sequence ## Content # Bootstrap Sequence After the Web Host receives its configuration it runs a fixed initialization sequence before rendering any UI. The sequence differs slightly depending on whether the Web Host is loaded as a JS module that takes over the page (the standard facade path) or runs inside an iframe (the manual, facade-less path), but the internal steps after configuration is available are identical. ## Path A — JS Module (Standard, facade path) This is the path the current `wippy/facade` uses. The facade serves a page that loads a Web Host JS-module entry — `module.js` for **compat** mode or `managed-layout.js` for **managed** mode — and the module takes over the whole page and its browser history. 1. **Page loads the module.** The script registers `window.initWippyApp` on the page's `window`. 2. **Page calls `initWippyApp(config, rootContainer?)`.** The page has fetched `/facade/config` and passes the payload directly as a function argument. There is no PostMessage handshake. ```javascript const events = window.initWippyApp(config, '#app') events.on('ready', () => console.log('App ready')) ``` 3. **Initialization proceeds** — see [Internal Init Sequence](#internal-init-sequence) below. ## Path B — Iframe (manual, facade-less) This is the path taken when you embed the full host inside an iframe yourself — for partial-page embedding with stronger isolation. It loads `iframe.html?waitForCustomConfig` and receives config via a `SetConfig` PostMessage. The current facade does not produce this; it exists for manual insertions. 1. **Iframe loads.** The Web Host loads in the browser. Because `?waitForCustomConfig` is present in the URL, the app mounts a minimal skeleton and suspends — it does not attempt to read auth tokens or call any API endpoints yet. 2. **Parent sends `SetConfig`.** The parent has fetched `/facade/config` (or supplied an equivalent payload) and forwards it via PostMessage: ```javascript iframe.contentWindow.postMessage( { type: '@gen2-chat', action: 'set-config', ...configPayload }, config.iframe_origin ) ``` 3. **Web Host receives `AppConfig`.** The message handler validates the envelope type and action, then extracts the full configuration object. 4. **Initialization proceeds** — the internal path is identical to Path A from this point forward. ## Internal Init Sequence Once `AppConfig` is available (via either path), the Web Host runs the following steps in order: **1. Pinia store initialization.** The root Pinia instance is created and all store modules are registered. Auth state is loaded from `AppConfig.auth` — the token is stored in memory (or in a cookie if `hostConfig.session.type = 'cookie'`). Environment URLs from `AppConfig.env` are written to the store for use by Axios and the WebSocket client. **2. Axios configuration.** The Axios instance is configured with `APP_API_URL` as `baseURL` and the auth token injected as a default header. Any `axiosDefaults` from the config are merged in. This instance is the one child iframes receive via the proxy API. **3. Vue Router initialization.** The router is created with the history mode specified in `AppConfig.hostConfig.history` (`"hash"` or `"browser"`). System routes (`/c/:id`, `/chat/:id`, `/keeper/:id`, etc.) are registered. This is a static set — dynamic mount routes are added in a later step. **4. PrimeVue and theme injection.** PrimeVue is installed on the Vue app. CSS custom properties from `AppConfig.theming.global` and `AppConfig.theming.host` are injected as `:root { --key: value; }` overrides for the appropriate scopes. `customCSS` strings from `theming.global` and `theming.host` are injected as `