Registry Entries
A registry entry declares a frontend artifact to the Wippy backend so the Web
Host can discover and serve it. The artifact can be a micro frontend app or a
reusable web component. Its declaration spans the module's _index.yaml, the
wippy block in package.json, and the generated wippy-meta.json file.
For the wippy/views module setup that processes these entries at runtime, see Views.
What a Registry Entry Is
Every frontend artifact is declared as a registry.entry in the module's _index.yaml. The kind: registry.entry marker tells the Wippy registry that this entry carries metadata consumed by other modules rather than defining a Lua component directly.
Common trap:
view.pageandview.componentare notkindvalues. Always writekind: registry.entryand put the frontend artifact type inmeta.type.kind: view.pageandkind: view.componentare invalid shapes.
Minimal correct shape:
- name: main
kind: registry.entry
meta:
type: view.page
version: "1.0"
namespace: app.views
entries:
- name: main
kind: registry.entry
meta:
type: view.page
name: main
title: Admin Panel
icon: tabler:layout-dashboard
order: 0
announced: true
secure: false
url: /app
base_path: app/main
entry_point: app.html
mountRoute: /home/:part(.*)*
The meta block is what wippy/views reads. The meta.type field discriminates between the two supported artifact kinds.
The meta.type Discriminator
| Value | Meaning |
|---|---|
view.page |
A micro frontend app (full SPA), rendered through the page's selected iframe or Web Fragment engine |
view.component |
A Web Component (custom element) that can be embedded anywhere in a page |
Every other field in meta is interpreted in the context of this type. Fields that apply to one type and not the other are described in the per-type reference pages (view.page, view.component).
The specification Marker
Frontend packages should declare "specification": "wippy-component-1.0" at the top level of package.json. The marker identifies the package metadata and API response shape. @wippy-fe/vite-plugin validates the value when it is present.
{
"name": "@wippy/example-widget",
"version": "1.0.0",
"specification": "wippy-component-1.0",
"browser": "dist/index.js",
"wippy": {
"type": "component",
"tagName": "example-widget"
}
}
The marker does not change rendering behavior. wippy/views carries the bundled value into page and component descriptors, or supplies wippy-component-1.0 for legacy bundles that omit it; registry YAML validation does not depend on this field.
The wippy-meta.json Contract
@wippy-fe/vite-plugin emits a wippy-meta.json file alongside the built
bundle. It is the canonical source for the artifact-authored runtime metadata:
props schema, events schema, title, icon, and proxy injection settings.
Metadata responsibilities:
- Emitted by:
wippyPagePlugin()forview.pageapps andwippyComponentPlugin()forview.componentweb components. - Generated from:
package.json; do not hand-authorwippy-meta.json. - Consumed by:
wippy/views, which reads it from the served bundle root when building page/component descriptors and API responses. - Overridden by:
_index.yaml, which remains authoritative for deployment policy and every field it explicitly declares.
When wippy/views loads a registry.entry, it reads wippy-meta.json from the artifact's served bundle root (url + base_path) for both pages and components. YAML always wins: _index.yaml takes precedence for every field it declares. wippy-meta.json provides the defaults that wippy/views reads when no YAML override is present for a given field. Deployment-policy fields — announced, secure, url, mountRoute, and base_path — must be set in _index.yaml because they express operator decisions rather than component authorship; there is no package.json/wippy-meta.json authoring surface for them. (base_path is honored for both pages and components; the current app-template component entries simply omit it.)
By contrast, entry_point is FE-authored and YAML-overridable. For pages it comes from wippy.path (which @wippy-fe/vite-plugin requires; omitting it makes the plugin throw wippy.path is required for a page package). For components it comes from the top-level browser field; wippy.tagName declares the custom-element name separately. The meta.entry_point field in _index.yaml is an optional per-deployment override on top of that authored default; it is not a YAML-only field.
A component author writes display metadata once in the wippy block of
package.json, and the vite plugin records it in wippy-meta.json as the
author defaults. The operator sets routing and access policy in YAML and can
also override display fields there.
Common Fields
These fields appear in the meta block for both view.page and view.component entries.
| Field | Type | Default | Description |
|---|---|---|---|
type |
string | — | view.page or view.component (required) |
name |
string | entry name | Identifier used in API responses |
title |
string | — | Human-readable display name |
icon |
string | — | Iconify reference, e.g. tabler:layout-dashboard |
announced |
boolean | — | Controls visibility in listing APIs; semantics differ by type (see below) |
secure |
boolean | false |
Requires authentication to access |
url |
string | — | Base URL prefix for static file serving (CDN origin or local mount path) |
entry_point |
string | index.html / index.js |
Entry file name within the static directory |
announced Semantics by Type
The announced flag has different consequences depending on meta.type:
-
view.page: controls whether the page appears in the navigation sidebar (GET /api/public/pages/list). Settingannounced: falsehides the page from navigation but the page still loads if accessed directly. This is a legitimate pattern for embedded or auxiliary pages. -
view.component: gates inclusion inGET /api/public/components/list. Ifannounced: false, the component is excluded from that endpoint entirely, which means the Web Host never injects its script tag andcustomElements.get(tagName)stays undefined. For components that need autoload,announced: trueis required — see view.component for details.
How Serving Fields Combine
For micro frontend apps, the three fields compose to produce the HTML URL the Web Host loads:
<url>/<base_path>/<entry_point>
For example, with url: /app, base_path: app/main, entry_point: app.html, the host fetches /app/app/main/app.html.
The separation between base_path and entry_point is intentional. The Web Host injects <url>/<base_path>/ as an HTML <base> tag into the loaded page, which governs how the browser resolves all relative URLs inside that page. The entry file may sit in a subdirectory of the base — what matters is that the base points to the common root from which all resources can be reached relatively.
For example, if a bundle has this layout:
static/
shared/
vendor.js
app/
index.html ← entry_point: app/index.html
app.js
and index.html references ../shared/vendor.js, then base_path must point to static/ (the directory containing both app/ and shared/), not to app/. Setting base_path: app would make ../shared/vendor.js resolve outside the served directory and 404.
In the common case where all assets sit alongside the entry file, base_path and the directory containing entry_point are the same level, so the distinction is invisible. It only matters when a bundle shares resources across sibling directories.
For web components, the host composes the served URL the same way:
<url>/<base_path>/<entry_point>
The current app-template component entries omit base_path, but it is supported and composes the same way (<url>/<base_path>/<entry_point>) — so in those entries the URL collapses to <url>/<entry_point>. The difference from pages is that a component is injected as a <script type="module"> rather than getting its own injected HTML <base> tag.