Micro Frontend Apps (view.page)

A view.page entry describes a full single-page application that the Web Host loads through the selected iframe or Web Fragment engine. Each entry can claim a path in the host router and receives CSS, configuration, and host APIs through the engine's proxy adapter.

Frontend Fields (package.json wippy block)

These fields are authored by the FE developer in the wippy block of package.json. The vite plugin bakes them into wippy-meta.json at build time, and wippy/views reads them from there as defaults.

All fields in this section can be overridden by the operator in _index.yaml. YAML always takes precedence.

Display and Navigation

Field Type Default Description
title string — Label shown in the navigation sidebar and browser tab
icon string — Iconify icon reference, e.g. tabler:layout-dashboard
type string — Must be "page"
path string — Path to the built HTML entry file within the bundle output directory

Render engine

renderEngine selects the page render engine for this page (view.page only). The proxy API is portable across engines, but browser layout and DOM behavior can differ; review the fragment limitations before opting a page into that engine.

Value Effect
"auto" (default, or omitted) Follow the deployment's global switch (hostConfig.renderEngine, set by the facade render_engine parameter).
"iframe" Always render as a srcdoc iframe, regardless of the switch. Use for pages with reframed-incompatible tech — pointer hit-testing (elementFromPoint), viewport-unit (vh/vw, matchMedia) layout, position: fixed.
"fragment" Prefer the Web Fragment engine. Under a global-fragment deployment: always. Under a global-iframe deployment: only if a runtime capability probe confirms the /@fragment gateway + proxy are present (fail-safe to iframe otherwise).
{
  "wippy": {
    "type": "page",
    "renderEngine": "auto"
  }
}

See Render Engines for the full engine model and fragment limitations.

Proxy Configuration

Proxy injection has two surfaces. The FE developer authors defaults in the frontend package.json wippy block with lower-camel-case keys (themeConfig, primevue, customCss); the Vite plugin bakes them into wippy-meta.json. The operator overrides them with a proxy: block under meta: in registry YAML. Registry fields follow their documented schema rather than a universal casing rule. Nested proxy keys retain their defined lower-camel-case names, and the host deep-merges that YAML over the baked frontend defaults without converting keys.

{
  "wippy": {
    "type": "page",
    "proxy": {
      "enabled": true,
      "injections": {
        "css": {
          "themeConfig": true,
          "iframe": true,
          "primevue": true,
          "markdown": false,
          "customCss": true,
          "customVariables": true
        },
        "tailwindConfig": false,
        "resizeObserver": false,
        "preventLinkClicks": false,
        "iconifyIcons": false,
        "errorCapture": true
      }
    }
  }
}

In the iframe engine, proxy.injections configures the assets added by the srcdoc proxy. If it is omitted, that adapter uses permissive defaults and enables most injections. Web Host 1.0.56 carries proxy.enabled as metadata but does not use it as a runtime toggle.

Web Host 1.0.56 does not translate these flags to the Fragment engine. The Fragment gateway always supplies loading.js, proxy-fragment.js, and the four Host stylesheets (theme config, iframe scrollbar styles, PrimeVue/Tailwind, and Markdown); its proxy also installs error capture unconditionally. A page that can fall back to iframe should still declare its iframe injection intent explicitly.

The list below shows the recommended explicit iframe values for a typical Vite micro frontend app — not the runtime defaults — so package reviewers can see the page's fallback behavior.

These are the flags a micro frontend app typically declares for its iframe delivery path. They are not the runtime defaults, and Web Host 1.0.56's Fragment gateway does not use them.

  • css.themeConfig (true) — CSS custom properties for the active theme
  • css.iframe (true) — required default themed scrollbar styling; iframe is a historical name and the current sheet does not provide layout resets
  • css.primevue (true) — PrimeVue component base styles
  • css.markdown (false) — markdown rendering styles
  • css.customCss (true) — child-projected custom CSS
  • css.customVariables (true) — child-projected CSS variable overrides
  • tailwindConfig (false) — host Tailwind config object (CDN Tailwind only)
  • resizeObserver (false for full SPAs) — child body-size updates to the host
  • preventLinkClicks (false for pages) — install the iframe engine's raw-<a> classifier hook; use @wippy-fe/router for portable link classification across engines
  • iconifyIcons (false) — pre-load host Iconify collections
  • errorCapture (true) — forward uncaught page errors to the host

Most full SPA pages set resizeObserver: false and preventLinkClicks: false because they manage their own layout and routing. The main app in the template sets errorCapture: true to surface uncaught errors during development.

There is no dedicated web-font injection flag. Google Fonts are delivered through theming.global.customCSS (an @import in the theme's custom CSS), injected by the existing css.customCss flag.

Full flag reference and runtime defaults: CSS Injection.

Operator Configuration (_index.yaml)

These fields are set by the operator in the meta block of the _index.yaml registry entry. Most of them — announced, secure, url, base_path, mountRoute, auto_register, inline — represent deployment policy (routing, access control, and serving) that only makes sense at deploy time and has no package.json authoring surface. The one exception is entry_point: it is FE-authored (the vite plugin requires wippy.path in package.json and bakes it into wippy-meta.json), and the meta.entry_point field is only an optional per-deployment override of that baked default.

Required YAML shape: a page entry is kind: registry.entry with meta.type: view.page. Do not write kind: view.page.

- name: main
  kind: registry.entry
  meta:
    type: view.page
    name: main

URL and File Serving

Field Type Default Description
url string — Base URL prefix where the bundle is mounted (CDN origin or local http.static path). YAML-only — no package.json surface
base_path string — Subdirectory within the static mount. YAML-only — no package.json surface
entry_point string index.html HTML file to load; combined with url and base_path. FE-authored as wippy.path in package.json (baked into wippy-meta.json); the YAML value is an optional per-deployment override

The resolved entry URL is <url>/<base_path>/<entry_point>. An operator deploys the same bundle under multiple entries by pointing different _index.yaml entries at the same base_path with different entry_point or config_overrides values.

Unlike url and base_path, entry_point is not a deploy-only field. It is authored by the FE developer as wippy.path in the package.json wippy block and baked into wippy-meta.json by the vite plugin — the plugin requires it and throws wippy.path is required for a page package if it is omitted. The meta.entry_point field in _index.yaml only overrides that baked default per deployment; the resolution order is YAML entry_point → bundled wippy.path → index.html.

Visibility and Access

Field Type Default Description
announced boolean — true → page appears in GET /api/public/pages/list and the nav sidebar
secure boolean false true → requires authentication; unauthenticated requests get a 401
inline boolean false true → page is hidden from all listings (sidebar, API); use for embedded artifact viewers or auxiliary routes

announced: false hides the page from navigation but does not prevent loading. The page can still be embedded or reached through its route. inline: true is stricter — it suppresses the page from all public-facing listings.

Mount Route

Field Type Default Description
mountRoute string — Claims a URL path in the host router; the host renders this page when the browser navigates to a matching path

Casing exception: the current registry schema reads meta.mountRoute and stores it in the registry's internal mount_route field; API output uses mountRoute again. Use the authored lower-camel-case spelling shown here.

mountRoute accepts only the v1 catch-all form — /:part(.*)* (root) or /<literal-prefix>/:part(.*)*, where the prefix is one or more lowercase-alphanumeric-plus-hyphen segments ending in the required :part(.*)* wildcard. Arbitrary Vue Router patterns — named params, custom regex, or a different param name (e.g. /home/:id, /users/:userId(\d+)) — are rejected: the backend records a syntax mount-route conflict, GET /api/public/pages/routes returns HTTP 500, and Host startup stops with the error relayed through the Host error handler. The :part(.*)* wildcard lets the child application manage its own sub-routes while the host keeps ownership of the top-level path.

mountRoute: /home/:part(.*)*

When the Web Host starts, it fetches GET /api/public/pages/routes and calls router.addRoute() for each entry that has a mountRoute. See Dynamic Routing for the full sync mechanism.

Per-Page Configuration Overrides

Field Type Description
config_overrides object Deep-merged over the AppConfig values the Web Host injects into the page context

config_overrides is the registry wrapper name. Its nested object already uses the frontend schema's lower-camel-case keys, such as customization.customCSS and customization.cssVariables. The Web Host deep-merges those exact keys on top of bundled wippy.configOverrides from wippy-meta.json; the YAML value wins per nested key.

config_overrides changes the page's injected AppConfig. It does not change proxy injection flags. In particular, config_overrides never affects proxy.injections, wippy.proxy.injections, or the runtime defaults for CSS/script injection. To override proxy injection flags for a deployment, use meta.proxy as described in Operator proxy override.

A typical use case is running the same bundle with a custom colour palette:

- name: iframe-demo-themed
  kind: registry.entry
  meta:
    type: view.page
    name: iframe-demo-themed
    title: Iframe Demo (Custom Palette)
    icon: tabler:paint
    order: 4
    announced: false
    secure: false
    url: /app
    base_path: app/iframe-demo
    entry_point: app.html
    mountRoute: /demo-themed/:part(.*)*
    config_overrides:
      customization:
        cssVariables:
          "--p-primary": "#7c9ed9"
          "--p-primary-color": "#7c9ed9"
          "--p-danger": "#e8a0a0"
        customCSS: |
          /* Palette values here are an intentional page-theme definition, not module CSS. */
          :root { font-family: var(--wippy-brand-font, sans-serif); }          

Note that announced: false is valid for view.page entries — the page is reachable via its mountRoute but does not appear in the sidebar.

Operator proxy override (_index.yaml)

The proxy injection defaults baked into wippy-meta.json (from the package.json wippy block) can be overridden per deployment with a proxy: block placed under meta: in the registry entry. Facade requirement names use their documented snake_case names. The wrapper is config_overrides, while the registry schema defines the route field as mountRoute, stores it in the registry's internal mount_route field, and emits mountRoute in API output. Nested proxy/config objects are passed through and retain their defined lower-camel-case keys. The host deep-merges meta.proxy over bundled wippy.proxy.

Use meta.proxy, not data.proxy. Keep top-level backend fields such as config_overrides in snake_case, but preserve nested proxy/config keys such as themeConfig and customCss; keep the injections wrapper. Do not invent meta.config or meta.configOverrides; the exact per-page override wrapper is meta.config_overrides.

Keep the two frontend spellings distinct:

  • Backend meta.proxy.injections.css.customCss remains wippy.proxy.injections.css.customCss.
  • Backend meta.config_overrides.customization.customCSS projects to frontend wippy.configOverrides.customization.customCSS and runtime config.theming.global.customCSS.
  • Do not invent an appConfig wrapper around either frontend shape.
- name: dashboard
  kind: registry.entry
  meta:
    type: view.page
    name: dashboard
    url: /app
    base_path: app/dashboard
    entry_point: app.html
    proxy:
      enabled: true
      injections:
        css:
          themeConfig: true
          iframe: true
          primevue: true
          customCss: true
          customVariables: true
        tailwindConfig: false
        iconifyIcons: false

Only the keys you set are overridden; everything else keeps the value baked into wippy-meta.json. Full flag reference and runtime defaults: CSS Injection.