Hilla Documentation

Nested Views

Nested views: route configuration, styling, creating navigation menus, and using the tab component.

In many typical applications, you have a main view that displays a menu allowing the user to choose a child view to display. When the user selects an item from the menu, a specific child view is shown in a content area inside the main view.

nested views
Nested Views

You can define such a main view on either the server side or the client side. However, if you intend to display any client-side child views, the main view must be a client-side view.

A main view typically:

  • imports Lumo theme global styles,

  • establishes the nested view structure with <vaadin-app-layout>,

  • creates a navigation menu bar,

  • generates menu links using the router instance,

  • has a binding for the selected tab.

You can have multiple such main views.

Route Configuration

In a nested view configuration, you have a route to the main view, and child routes to the sub-views. The route to the main view is usually the root route. You can configure the child views either with explicit full paths, such as /main-view/users, or hierarchically with child routes, as follows.

The following configuration in routes.ts sets up a main view with two child views:

const routes = [
{
	path: '',
	component: 'main-view',
	children: [
		{
			path: '',
			component: 'hello-world-view',
		},
		{
			path: 'about',
			component: 'about-view',
			action: async () => { await import ('./views/about/about-view'); }
		}
	]
},
];

Establish an Application Layout

The most prominent feature of the main layout is that it defines the layout for the application. You can use the App Layout component:

import { css, html, LitElement } from 'lit';
import { customElement } from 'lit/decorators.js';
import { Layout } from './view';
import '@vaadin/app-layout';

@customElement('main-layout')
export class MainLayout extends Layout {
  render() {
    return html`
      <vaadin-app-layout>
        <slot></slot>
      </vaadin-app-layout>
    `;
  }
}
Note
Keep the <slot> in the main layout template returned from the render() method. Hilla Router adds views as children in the main layout.

Create the Navigation Menu

The main layout usually contains a navigation bar with the menu. Here, we create the navigation bar with menu using plain anchor tags:

import { css, html, LitElement } from 'lit';
import { customElement } from 'lit/decorators.js';
import { Layout } from './view';
import '@vaadin/app-layout';

@customElement('main-layout')
export class MainLayout extends Layout {
  render() {
    return html`
      <vaadin-app-layout id="layout">
        <div slot="drawer">
          <a href="/">Hello world</a>
          <a href="/about">About</a>
        </div>
        <slot></slot>
      </vaadin-app-layout>
    `;
  }
}

Create Header

The Vaadin App Layout supports a header by adding content to the navbar slot.

import { css, html, LitElement } from 'lit';
import { customElement } from 'lit/decorators.js';
import { Layout } from './view';
import '@vaadin/app-layout';
import '@vaadin/app-layout/vaadin-drawer-toggle.js';

@customElement('main-layout')
export class MainLayout extends Layout {
  render() {
    return html`
      <vaadin-app-layout id="layout">
        <header slot="navbar">
          <vaadin-drawer-toggle aria-label="Menu toggle">
          </vaadin-drawer-toggle><!--(1)-->
          <h1>App Title</h1>
        </header>
        <div slot="drawer">
          <a href="/">Hello world</a>
          <a href="/about">About</a>
        </div>
        <slot></slot>
      </vaadin-app-layout>
    `;
  }
}
  1. Adding the <vaadin-drawer-toggle> element will show a toggle for hiding and showing the navigation drawer.