App shell and menus
The app shell is what surrounds every page of a mount: the title and logo, the navigation variant, the header widgets and switches, and the menu. It is one of the building blocks.
An app shell is not a page. Its content area shows the current route’s page, and when the URL is the mount’s root it shows the home route. The shell only draws the chrome around that slot.
The menu
Section titled “The menu”The menu is a list of entries, and every entry is one of these:
| Entry | What a click does |
|---|---|
RouteLink | navigates to a route of the mount (or to a full URL) |
RuleLink | runs client-side rules, typically one RunAction naming an action, instead of navigating |
Menu | a group of entries, nestable. presentation: {display: cards} (or @Menu(display = MenuDisplay.cards)) opens it as a panel of cards |
RemoteMenu | the menu of another Mateu service, fetched at runtime. This is how federation composes several UIs into one console |
A menu leaf is therefore a route or a rule. A leaf that routes somewhere the caller may not
reach is not sent: a RouteLink inherits its route’s access:.
A group can open as a panel of cards: presentation: {display: cards} on the Menu, and a
description plus presentation: {icon: …} or {image: …} on each entry; an entry that is itself a
Menu becomes a card whose entries are its actions. See Card menus.
- type: Menu label: Quick access presentation: {display: cards} submenu: - type: RouteLink label: Check-in route: check-in description: Sign the registration card and scan the ID presentation: {icon: "vaadin:clipboard"}Authoring it
Section titled “Authoring it”The product catalogue’s shell has one link and one leaf that runs the catalogue’s newProduct
flow:
# specs/ui/app.yaml — bound to the mount root ("") in routes.yamltype: AppShelltitle: Cataloguevariant: MENU_ON_TOPthemeToggle: truemenu: - type: RouteLink label: Products route: products - type: RuleLink label: New product rules: - action: RunAction actionId: newProductwidgets: - type: Text text: "v1.0"In Java the mount class carries the shell: @App for the chrome and @Menu fields for the menu.
A field’s type decides what kind of entry it becomes:
@UI("")@App(value = AppVariant.MENU_ON_TOP, themeToggle = true)@Title("Catalogue")public class Catalogue { @Menu Products products; // a page @Menu RouteLink archived = new RouteLink("/products/archived", "Archived");}For a menu that depends on the user, configuration or a database, implement AppSupplier, which
returns a fluent AppShell, or MenuSupplier, which returns just the menu. Both are evaluated per
request. C# uses [App] with [MenuItem] methods, or IAppSupplier / IMenuSupplier. Python uses
@app with @menu_item, or AppSupplier / MenuSupplier.
The home page
Section titled “The home page”The home page is the route the shell opens on. It resolves in this order: the shell’s own
homeRoute:, then the mount’s home:, then the first navigable menu item.
Served vs static
Section titled “Served vs static”- Served: the server builds the shell per request, so access rules,
AppSuppliers and translated labels are applied before anything reaches the browser. - Static: the bundle ships the shell. The shell’s flows (
actions:withsteps) and catalogue actions are lowered to commands that run in the browser, so aRuleLinkworks with no backend. Access rules can’t be checked without a server, so they are cosmetic there. - Ports: .NET and Python have no
type: AppShellfile. They declare the shell in code, and they do carry the action catalogue.
See also
Section titled “See also”- Structure of an app: the shell variants, the app header, overlays and page anatomy.
- App shell as data: every key of
type: AppShell, flows and widgets. - Navigation and menus: the six kinds of
@Menuentry, and shells in code. - Application shell: variants and layout.
- UI federation.