> Markdown version of [App Layout](https://vaadin.com/docs/latest/components/app-layout). Section index: [llms.txt](https://vaadin.com/docs/latest/components/llms.txt)

# App Layout

App Layout is a component for the root layout of a Vaadin application. It provides predefined areas for the navigation drawer, the header, and the view’s content.

> **Important: Scaled down examples**
>
> The examples on this page are scaled down so that their viewport-size-dependent behavior can be demonstrated. Some examples also change their behavior based on your browser viewport size.

**Lit** — `app-layout-basic.ts`

```html
<vaadin-app-layout>
  <vaadin-drawer-toggle slot="navbar"></vaadin-drawer-toggle>
  <h1 slot="navbar">MyApp</h1>
  <vaadin-scroller slot="drawer">
    <vaadin-side-nav style="margin: var(--vaadin-gap-s)">
      <vaadin-side-nav-item path="/dashboard">
        <vaadin-icon icon="vaadin:dashboard" slot="prefix"></vaadin-icon>
        Dashboard
      </vaadin-side-nav-item>
      <vaadin-side-nav-item path="/orders">
        <vaadin-icon icon="vaadin:cart" slot="prefix"></vaadin-icon>
        Orders
      </vaadin-side-nav-item>
      <vaadin-side-nav-item path="/customers">
        <vaadin-icon icon="vaadin:user-heart" slot="prefix"></vaadin-icon>
        Customers
      </vaadin-side-nav-item>
      <vaadin-side-nav-item path="/products">
        <vaadin-icon icon="vaadin:package" slot="prefix"></vaadin-icon>
        Products
      </vaadin-side-nav-item>
      <vaadin-side-nav-item path="/documents">
        <vaadin-icon icon="vaadin:records" slot="prefix"></vaadin-icon>
        Documents
      </vaadin-side-nav-item>
      <vaadin-side-nav-item path="/tasks">
        <vaadin-icon icon="vaadin:list" slot="prefix"></vaadin-icon>
        Tasks
      </vaadin-side-nav-item>
      <vaadin-side-nav-item path="/analytics">
        <vaadin-icon icon="vaadin:chart" slot="prefix"></vaadin-icon>
        Analytics
      </vaadin-side-nav-item>
    </vaadin-side-nav>
  </vaadin-scroller>
</vaadin-app-layout>
```

**Flow** — `AppLayoutBasic.java`

```java
public class AppLayoutBasic extends AppLayout {

    public AppLayoutBasic() {
        DrawerToggle toggle = new DrawerToggle();

        H1 title = new H1("MyApp");
        title.getStyle().set("font-size", "1.125rem").set("margin", "0");

        SideNav nav = getSideNav();
        nav.getStyle().set("margin", "var(--vaadin-gap-s)");

        Scroller scroller = new Scroller(nav);

        addToDrawer(scroller);
        addToNavbar(toggle, title);
    }
}
```

**React** — `app-layout-basic.tsx`

```tsx
<AppLayout>
  <DrawerToggle slot="navbar" />
  <h1 slot="navbar" style={h1Style}>
    MyApp
  </h1>
  <Scroller slot="drawer">
    <SideNav ref={sideNavRef} style={{ margin: 'var(--vaadin-gap-s)' }}>
      <SideNavItem path="/dashboard">
        <Icon icon="vaadin:dashboard" slot="prefix" />
        Dashboard
      </SideNavItem>
      <SideNavItem path="/orders">
        <Icon icon="vaadin:cart" slot="prefix" />
        Orders
      </SideNavItem>
      <SideNavItem path="/customers">
        <Icon icon="vaadin:user-heart" slot="prefix" />
        Customers
      </SideNavItem>
      <SideNavItem path="/products">
        <Icon icon="vaadin:package" slot="prefix" />
        Products
      </SideNavItem>
      <SideNavItem path="/documents">
        <Icon icon="vaadin:records" slot="prefix" />
        Documents
      </SideNavItem>
      <SideNavItem path="/tasks">
        <Icon icon="vaadin:list" slot="prefix" />
        Tasks
      </SideNavItem>
      <SideNavItem path="/analytics">
        <Icon icon="vaadin:chart" slot="prefix" />
        Analytics
      </SideNavItem>
    </SideNav>
  </Scroller>
</AppLayout>
```

The layout consists of three sections:

- [Content area](#content-area), a view content area;

- [Navbar](#navbar), a horizontal navigation bar; and

- [Drawer](#drawer), a collapsible navigation drawer-

An application’s main navigation blocks should be positioned in the `navbar` or the `drawer` or both, whereas views are rendered in the content area. App Layout is responsive and adjusts automatically to fit desktop, tablet, and mobile screen sizes.

## <a id="usage-as-root-layout"></a>Usage as Root Layout

App Layout is designed to be the application’s root layout, within which most or all views are rendered. It’s not intended to be nested inside other elements.

### <a id="flow"></a>Flow

With Flow, the root layout can be defined using the [`@Layout` annotation](https://vaadin.com/docs/latest/flow/routing/layout.md#automatic-layout-using-layout), which tells the router to render all routes or views inside of it.

```java
@Layout
public class MainLayout extends AppLayout {

}
```

### <a id="hilla"></a>Hilla

Files named `@layout.tsx` define the root layout for the other views defined in the same directory or its subdirectories. A `@layout.tsx` in the root of the `views` directory acts as the default root layout for all views in the application. An `<Outlet/>` element is used to tell the router where to render the contents of routes or views.

@layout.tsx

```tsx
export default function MainLayout() {
  return (
    <AppLayout>
      <Outlet />
    </AppLayout>
  );
}
```

See [Hilla routing documentation](https://vaadin.com/docs/latest/hilla/guides/routing.md#adding-layout-routes) for details.

## <a id="content-area"></a>Content Area

The content area is where individual views are rendered. The [route layout mechanisms in Flow and Hilla](#usage-as-root-layout) can automatically render the contents of routes and views there, but it can be invoked manually:

**Flow**

```java
public class MainLayout extends AppLayout {
  public MainLayout() {
    MyView view = new MyView();
    setContent(view);
  }
}
```

**React**

```tsx
<AppLayout>
  <MyView/>
</AppLayout>
```

**Lit**

```html
<vaadin-app-layout>
  <my-view></my-view>
</vaadin-app-layout>
```

## <a id="navbar"></a>Navbar

The `navbar` is a header above the content area. It can contain primary or secondary navigation elements, the application’s title, or view-specific content such as the title of the current view.

**Flow**

```java
@Layout
public class MainLayout extends AppLayout {
  public MainLayout() {
    H1 title = new H1("My App");
    addToNavbar(title);
  }
}
```

**React**

```tsx
<AppLayout>
  <h1 slot="navbar">
    My App
  </h1>
</AppLayout>
```

**Lit**

```html
<vaadin-app-layout>
  <h1 slot="navbar">My App</h1>
</vaadin-app-layout>
```

### <a id="navbar-placement"></a>Navbar Placement

The `navbar` can be located on top, or to the side of the `drawer`. When put it on top, the `navbar` is typically used as an application header. Application headers contain, for example, the application’s name and branding, as well as actions that apply to the entire application (e.g., notifications, settings, etc.).

**Lit** — `app-layout-navbar-placement.ts`

```html
<vaadin-app-layout>
  <vaadin-drawer-toggle slot="navbar"></vaadin-drawer-toggle>
  <h1 slot="navbar">MyApp</h1>
  <vaadin-scroller slot="drawer">
    <vaadin-side-nav style="margin: var(--vaadin-gap-s)">
      <vaadin-side-nav-item path="/dashboard">
        <vaadin-icon icon="vaadin:dashboard" slot="prefix"></vaadin-icon>
        <span>Dashboard</span>
      </vaadin-side-nav-item>
      <vaadin-side-nav-item path="/orders">
        <vaadin-icon icon="vaadin:cart" slot="prefix"></vaadin-icon>
        <span>Orders</span>
      </vaadin-side-nav-item>
    </vaadin-side-nav>
  </vaadin-scroller>
</vaadin-app-layout>
```

**Flow** — `AppLayoutNavbarPlacement.java`

```java
public class AppLayoutNavbarPlacement extends AppLayout {

    public AppLayoutNavbarPlacement() {
        DrawerToggle toggle = new DrawerToggle();

        H1 title = new H1("MyApp");
        title.getStyle().set("font-size", "1.125rem").set("margin", "0");

        SideNav nav = getSideNav();
        nav.getStyle().set("margin", "var(--vaadin-gap-s)");

        Scroller scroller = new Scroller(nav);

        addToDrawer(scroller);
        addToNavbar(toggle, title);
    }
}
```

**React** — `app-layout-navbar-placement.tsx`

```tsx
<AppLayout>
  <DrawerToggle slot="navbar" />
  <h1 slot="navbar" style={h1Style}>
    MyApp
  </h1>

  <Scroller slot="drawer">
    <SideNav ref={sideNavRef} style={{ margin: 'var(--vaadin-gap-s)' }}>
      <SideNavItem path="/dashboard">
        <Icon icon="vaadin:dashboard" slot="prefix" />
        Dashboard
      </SideNavItem>
      <SideNavItem path="/orders">
        <Icon icon="vaadin:cart" slot="prefix" />
        Orders
      </SideNavItem>
      <SideNavItem path="/customers">
        <Icon icon="vaadin:user-heart" slot="prefix" />
        Customers
      </SideNavItem>
      <SideNavItem path="/products">
        <Icon icon="vaadin:package" slot="prefix" />
        Products
      </SideNavItem>
      <SideNavItem path="/documents">
        <Icon icon="vaadin:records" slot="prefix" />
        Documents
      </SideNavItem>
      <SideNavItem path="/tasks">
        <Icon icon="vaadin:list" slot="prefix" />
        Tasks
      </SideNavItem>
      <SideNavItem path="/analytics">
        <Icon icon="vaadin:chart" slot="prefix" />
        Analytics
      </SideNavItem>
    </SideNav>
  </Scroller>
</AppLayout>
```

When placed to the side, the `navbar` is often seen as a view header, containing the view’s title, as well as actions and secondary navigation that relate only to the current view.

**Lit** — `app-layout-navbar-placement-side.ts`

```html
<vaadin-app-layout primary-section="drawer">
  <vaadin-drawer-toggle slot="navbar"></vaadin-drawer-toggle>
  <h1 slot="navbar">Dashboard</h1>
  <vaadin-scroller slot="drawer">
    <vaadin-side-nav style="margin: var(--vaadin-gap-s)">
      <vaadin-side-nav-item path="/dashboard">
        <vaadin-icon icon="vaadin:dashboard" slot="prefix"></vaadin-icon>
        Dashboard
      </vaadin-side-nav-item>
      <vaadin-side-nav-item path="/orders">
        <vaadin-icon icon="vaadin:cart" slot="prefix"></vaadin-icon>
        Orders
      </vaadin-side-nav-item>
    </vaadin-side-nav>
  </vaadin-scroller>
</vaadin-app-layout>
```

**Flow** — `AppLayoutNavbarPlacementSide.java`

```java
public class AppLayoutNavbarPlacementSide extends AppLayout {

    public AppLayoutNavbarPlacementSide() {
        DrawerToggle toggle = new DrawerToggle();

        H1 title = new H1("Dashboard");
        title.getStyle().set("font-size", "1.125rem").set("margin", "0");

        SideNav nav = getSideNav();
        nav.getStyle().set("margin", "var(--vaadin-gap-s)");

        Scroller scroller = new Scroller(nav);

        addToDrawer(scroller);
        addToNavbar(toggle, title);

        setPrimarySection(Section.DRAWER);
    }
}
```

**React** — `app-layout-navbar-placement-side.tsx`

```tsx
<AppLayout primarySection="drawer">
  <DrawerToggle slot="navbar" />

  <h1 slot="navbar" style={h1Style}>
    Dashboard
  </h1>

  <Scroller slot="drawer">
    <SideNav ref={sideNavRef} style={{ margin: 'var(--vaadin-gap-s)' }}>
      <SideNavItem path="/dashboard">
        <Icon icon="vaadin:dashboard" slot="prefix" />
        Dashboard
      </SideNavItem>

      <SideNavItem path="/orders">
        <Icon icon="vaadin:cart" slot="prefix" />
        Orders
      </SideNavItem>
    </SideNav>
  </Scroller>
</AppLayout>
```

## <a id="drawer"></a>Drawer

The `drawer` can switch between a fixed area next to the view’s content and an expandable panel, toggled via the [drawer toggle](#drawer-toggle). It typically contains the application’s primary navigation, such as a [Side Navigation](https://vaadin.com/docs/latest/components/side-nav.md) component.

**Flow**

```java
@Layout
public class MainLayout extends AppLayout {
  public MainLayout() {
    SideNav nav = new SideNav();
    addToDrawer(nav);
  }
}
```

**React**

```tsx
<AppLayout>
  <SideNav slot="drawer">
    ...
  </SideNav>
</AppLayout>
```

**Lit**

```html
<vaadin-app-layout>
  <vaadin-side-nav slot="drawer">
    ...
  </vaadin-side-nav>
</vaadin-app-layout>
```

### <a id="drawer-toggle"></a>Drawer Toggle

Show and hide the `drawer` using a Drawer Toggle or a Button. The Drawer Toggle, which is represented by the hamburger icon (i.e., ☰), should always be accessible — unless the `drawer` is empty. It’s usually situated in the `navbar`.

## <a id="scrolling-behavior"></a>Scrolling Behavior

Depending on whether App Layout has a defined height, the way the content inside the layout scrolls can differ.

### <a id="auto-height"></a>Auto Height

When the App Layout has an undefined or auto height set, which is the default, the `<body>` element is the scrolling container for the content inside the layout.

**Lit** — `app-layout-height-auto.ts`

```html
<vaadin-app-layout>
  <h1 slot="navbar">MyApp</h1>
  <vaadin-grid .items="${this.items}" all-rows-visible>
    <vaadin-grid-column path="firstName"></vaadin-grid-column>
    <vaadin-grid-column path="lastName"></vaadin-grid-column>
    <vaadin-grid-column path="email"></vaadin-grid-column>
    <vaadin-grid-column path="profession"></vaadin-grid-column>
  </vaadin-grid>
</vaadin-app-layout>
```

**Flow** — `AppLayoutHeightAuto.java`

```java
public class AppLayoutHeightAuto extends AppLayout {

    public AppLayoutHeightAuto() {
        H1 title = new H1("MyApp");
        title.getStyle().set("font-size", "1.125rem").set("margin",
                "var(--vaadin-padding-m)");
        addToNavbar(title);

        Grid<Person> grid = new Grid<>(Person.class, false);
        grid.addColumn(Person::getFirstName).setHeader("First name");
        grid.addColumn(Person::getLastName).setHeader("Last name");
        grid.addColumn(Person::getEmail).setHeader("Email");
        grid.addColumn(Person::getProfession).setHeader("Profession");

        List<Person> people = DataService.getPeople(20);
        grid.setItems(people);
        grid.setAllRowsVisible(true);
        setContent(grid);
    }
}
```

**React** — `app-layout-height-auto.tsx`

```tsx
<AppLayout>
  <h1 slot="navbar" style={h1Style}>
    MyApp
  </h1>

  <Grid items={items.value} allRowsVisible>
    <GridColumn path="firstName" />
    <GridColumn path="lastName" />
    <GridColumn path="email" />
    <GridColumn path="profession" />
  </Grid>
</AppLayout>
```

The vertical scrollbar crosses the App Layout `navbar` and the content flows under it, allowing for translucent visual styles. Mobile browsers collapse and expand their toolbars when the user scrolls down and up, respectively. On iOS, you can tap the status bar (i.e., where signal strength, battery, and clock are indicated) to scroll back to the top of the page or view.

This behavior isn’t compatible with vertically scrollable Grids, or other scrolling containers within the content area that’s height is 100%. To support those, define 100% height for the App Layout.

### <a id="full-height-100"></a>Full Height (100%)

To allow a nested component to take all of the available vertical space inside the App Layout, you need to set an explicit height for the layout, typically 100%. A common use case is to let a data grid fill the entire content area.

> **Note:** Make sure all parent components and elements have 100% height. The full hierarchy of components from the App Layout to the `<body>` element need to have 100% height.

**Lit** — `app-layout-height-full.ts`

```html
<vaadin-app-layout style="height: 100%;">
  <h1 slot="navbar">MyApp</h1>
  <vaadin-grid .items="${this.items}" style="height: 100%;" theme="no-border">
    <vaadin-grid-column path="firstName"></vaadin-grid-column>
    <vaadin-grid-column path="lastName"></vaadin-grid-column>
    <vaadin-grid-column path="email"></vaadin-grid-column>
    <vaadin-grid-column path="profession"></vaadin-grid-column>
  </vaadin-grid>
</vaadin-app-layout>
```

**Flow** — `AppLayoutHeightFull.java`

```java
public class AppLayoutHeightFull extends AppLayout {

    public AppLayoutHeightFull() {
        H1 title = new H1("MyApp");
        title.getStyle().set("font-size", "1.125rem").set("margin",
                "var(--vaadin-padding-m)");
        addToNavbar(title);

        Grid<Person> grid = new Grid<>(Person.class, false);
        grid.addColumn(Person::getFirstName).setHeader("First name");
        grid.addColumn(Person::getLastName).setHeader("Last name");
        grid.addColumn(Person::getEmail).setHeader("Email");
        grid.addColumn(Person::getProfession).setHeader("Profession");

        List<Person> people = DataService.getPeople();
        grid.setItems(people);
        setContent(grid);

        getElement().getStyle().set("height", "100%");
        grid.setHeight("100%");
        grid.addThemeVariants(GridVariant.NO_BORDER);
    }
}
```

**React** — `app-layout-height-full.tsx`

```tsx
<AppLayout style={{ height: '100%' }}>
  <h1 slot="navbar" style={h1Style}>
    MyApp
  </h1>

  <Grid items={items.value} style={{ height: '100%' }} theme="no-border">
    <GridColumn path="firstName" />
    <GridColumn path="lastName" />
    <GridColumn path="email" />
    <GridColumn path="profession" />
  </Grid>
</AppLayout>
```

The vertical scrollbar stays within the layout content area, and mobile browsers don’t collapse their toolbars when the content area is scrolled down.

## <a id="bottom-navbar-on-small-touchscreens"></a>Bottom Navbar on Small Touchscreens

When the `navbar` is used for navigation, the *touch-optimized* `navbar` slot can be used to provide a separate version of the navigation at the bottom of the UI, optimized for mobile phones.

**Lit** — `app-layout-bottom-navbar.ts`

```html
<!-- --vaadin-app-layout-touch-optimized is only enforced as part of this example -->
<vaadin-app-layout style="--vaadin-app-layout-touch-optimized: true">
  <h1 slot="navbar">MyApp</h1>
  <vaadin-horizontal-layout
    slot="navbar touch-optimized"
    style="width: 100%; justify-content: space-evenly;"
  >
    <a
      href="/dashboard"
      aria-label="Dashboard"
      style="display: flex; align-items: center; padding: 0 1.5rem;"
    >
      <vaadin-icon icon="vaadin:dashboard"></vaadin-icon>
    </a>
    <a
      href="/orders"
      aria-label="Orders"
      style="display: flex; align-items: center; padding: 0 1.5rem;"
    >
      <vaadin-icon icon="vaadin:cart"></vaadin-icon>
    </a>
  </vaadin-horizontal-layout>
  <div class="content">
    <h2>View title</h2>
    <p>View content</p>
  </div>
</vaadin-app-layout>
```

**Flow** — `AppLayoutBottomNavbar.java`

```java
public class AppLayoutBottomNavbar extends AppLayout {

    public AppLayoutBottomNavbar() {
        H1 title = new H1("MyApp");
        title.getStyle().set("font-size", "1.125rem").set("margin",
                "var(--vaadin-padding-m) var(--vaadin-padding-l)");

        HorizontalLayout nav = getNavigation();

        H2 viewTitle = new H2("View title");
        Paragraph viewContent = new Paragraph("View content");

        Div content = new Div();
        content.add(viewTitle, viewContent);

        addToNavbar(title);
        addToNavbar(true, nav);

        setContent(content);
    }
}
```

**React** — `app-layout-bottom-navbar.tsx`

```tsx
<AppLayout ref={appLayoutRef}>
  <h1 slot="navbar" style={h1Style}>
    MyApp
  </h1>

  <HorizontalLayout
    slot="navbar touch-optimized"
    style={{ width: '100%', justifyContent: 'space-evenly' }}
    ref={horizontalLayoutRef}
  >
    <a href="/dashboard" aria-label="Dashboard" style={linkStyle}>
      <Icon icon="vaadin:dashboard" />
    </a>
    <a href="/orders" aria-label="Orders" style={linkStyle}>
      <Icon icon="vaadin:cart" />
    </a>
    <a href="/customers" aria-label="Customers" style={linkStyle}>
      <Icon icon="vaadin:user-heart" />
    </a>
    <a href="/products" aria-label="Products" style={linkStyle}>
      <Icon icon="vaadin:package" />
    </a>
  </HorizontalLayout>

  <div className="content">
    <h2>View title</h2>
    <p>View content</p>
  </div>
</AppLayout>
```

## <a id="best-practices"></a>Best Practices

### <a id="navbar-vs-drawer"></a>Navbar vs Drawer

Choose between `navbar` and `drawer` based primarily on the number of items placed in it. The `navbar` is a good choice for a small number of items (i.e., three to five), as they can fit into the viewport without scrolling.

**Lit** — `app-layout-navbar.ts`

```html
<vaadin-app-layout>
  <h1 slot="navbar">MyApp</h1>
  <vaadin-horizontal-layout
    slot="navbar"
    style="width: 100%; height: 2.25rem; justify-content: center; gap: 0.5rem"
  >
    <a
      href="/dashboard"
      style="display: flex; align-items: center; padding: 0 1rem; font-weight: 500; text-decoration: none"
    >
      Dashboard
    </a>
    <a
      href="/orders"
      style="display: flex; align-items: center; padding: 0 1rem; font-weight: 500; text-decoration: none"
    >
      Orders
    </a>
  </vaadin-horizontal-layout>
</vaadin-app-layout>
```

**Flow** — `AppLayoutNavbar.java`

```java
public class AppLayoutNavbar extends AppLayout {

    public AppLayoutNavbar() {
        H1 title = new H1("MyApp");
        title.getStyle().set("font-size", "1.125rem")
                .set("left", "var(--vaadin-padding-l)").set("margin", "0")
                .set("position", "absolute");

        HorizontalLayout navigation = getNavigation();
        navigation.getElement()

        addToNavbar(title, navigation);
    }
}
```

**React** — `app-layout-navbar.tsx`

```tsx
<AppLayout>
  <h1 slot="navbar" style={h1Style}>
    MyApp
  </h1>
  <HorizontalLayout
    ref={horizontalLayoutRef}
    slot="navbar"
    style={{ width: '100%', height: '2.25rem', justifyContent: 'center', gap: '0.5rem' }}
  >
    <a href="/dashboard" style={linkStyle}>
      Dashboard
    </a>
    <a href="/orders" style={linkStyle}>
      Orders
    </a>
    <a href="/customers" style={linkStyle}>
      Customers
    </a>
    <a href="/products" style={linkStyle}>
      Products
    </a>
  </HorizontalLayout>
</AppLayout>
```

When more items need to be displayed, or if small-screen support is a priority, the `drawer` is a better choice. It can accommodate a longer list of links without scrolling, and collapses into a hamburger menu on small screens. Furthermore, a vertical list of items is easier for the user to scan.

**Lit** — `app-layout-drawer.ts`

```html
<vaadin-app-layout primary-section="drawer">
  <vaadin-drawer-toggle slot="navbar"></vaadin-drawer-toggle>
  <h1 slot="navbar">Dashboard</h1>
  <vaadin-scroller slot="drawer">
    <vaadin-side-nav style="margin: var(--vaadin-gap-s)">
      <vaadin-side-nav-item path="/dashboard">
        <vaadin-icon icon="vaadin:dashboard" slot="prefix"></vaadin-icon>
        Dashboard
      </vaadin-side-nav-item>
      <vaadin-side-nav-item path="/orders">
        <vaadin-icon icon="vaadin:cart" slot="prefix"></vaadin-icon>
        Orders
      </vaadin-side-nav-item>
    </vaadin-side-nav>
  </vaadin-scroller>
</vaadin-app-layout>
```

**Flow** — `AppLayoutDrawer.java`

```java
public class AppLayoutDrawer extends AppLayout {

    public AppLayoutDrawer() {
        DrawerToggle toggle = new DrawerToggle();

        H1 title = new H1("Dashboard");
        title.getStyle().set("font-size", "1.125rem").set("margin", "0");

        SideNav nav = getTabs();
        nav.getStyle().set("margin", "var(--vaadin-gap-s)");

        Scroller scroller = new Scroller(nav);

        addToDrawer(scroller);
        addToNavbar(toggle, title);

        setPrimarySection(Section.DRAWER);
    }
}
```

**React** — `app-layout-drawer.tsx`

```tsx
<AppLayout primarySection="drawer">
  <DrawerToggle slot="navbar" />

  <h1 slot="navbar" style={h1Style}>
    Dashboard
  </h1>

  <Scroller slot="drawer">
    <SideNav ref={sideNavRef} style={{ margin: 'var(--vaadin-gap-s)' }}>
      <SideNavItem path="/dashboard">
        <Icon icon="vaadin:dashboard" slot="prefix" />
        Dashboard
      </SideNavItem>
      <SideNavItem path="/orders">
        <Icon icon="vaadin:cart" slot="prefix" />
        Orders
      </SideNavItem>
      <SideNavItem path="/customers">
        <Icon icon="vaadin:user-heart" slot="prefix" />
        Customers
      </SideNavItem>
      <SideNavItem path="/products">
        <Icon icon="vaadin:package" slot="prefix" />
        Products
      </SideNavItem>
      <SideNavItem path="/documents">
        <Icon icon="vaadin:records" slot="prefix" />
        Documents
      </SideNavItem>
      <SideNavItem path="/tasks">
        <Icon icon="vaadin:list" slot="prefix" />
        Tasks
      </SideNavItem>
      <SideNavItem path="/analytics">
        <Icon icon="vaadin:chart" slot="prefix" />
        Analytics
      </SideNavItem>
    </SideNav>
  </Scroller>
</AppLayout>
```

For applications that require multilevel or hierarchical navigation, use the `drawer` to contain at least the first level. The secondary and tertiary navigation items can be placed in either the `drawer` or the `navbar`.

**Lit** — `app-layout-secondary-navigation.ts`

```html
<vaadin-app-layout primary-section="drawer">
  <h1 slot="drawer">MyApp</h1>
  <vaadin-scroller slot="drawer">
    <vaadin-side-nav style="margin: var(--vaadin-gap-s)">
      <vaadin-side-nav-item path="/dashboard">
        <vaadin-icon icon="vaadin:dashboard" slot="prefix"></vaadin-icon>
        Dashboard
      </vaadin-side-nav-item>
      <vaadin-side-nav-item path="/orders">
        <vaadin-icon icon="vaadin:cart" slot="prefix"></vaadin-icon>
        Orders
      </vaadin-side-nav-item>
    </vaadin-side-nav>
  </vaadin-scroller>
  <vaadin-vertical-layout slot="navbar">
    <vaadin-horizontal-layout style="align-items: center;">
      <vaadin-drawer-toggle
        style="margin-inline-end: var(--vaadin-gap-s)"
      ></vaadin-drawer-toggle>
      <h2>Orders</h2>
    </vaadin-horizontal-layout>
    <vaadin-horizontal-layout
      id="navigation"
      style="height: 2.25rem; justify-content: center; gap: 0.5rem"
    >
      <a
        href="/all"
        style="display: flex; align-items: center; padding: 0 1rem; font-weight: 500; text-decoration: none"
      >
        All
      </a>
      <a
        href="/open"
        style="display: flex; align-items: center; padding: 0 1rem; font-weight: 500; text-decoration: none"
      >
        Open
      </a>
    </vaadin-horizontal-layout>
  </vaadin-vertical-layout>
</vaadin-app-layout>
```

**Flow** — `AppLayoutSecondaryNavigation.java`

```java
public class AppLayoutSecondaryNavigation extends AppLayout {

    public AppLayoutSecondaryNavigation() {
        H1 appTitle = new H1("MyApp");
        appTitle.getStyle().set("font-size", "1.125rem")
                .set("line-height", "2.75rem")
                .set("margin", "0 var(--vaadin-padding-m)");

        SideNav views = getPrimaryNavigation();
        views.getStyle().set("margin", "var(--vaadin-gap-s)");

        Scroller scroller = new Scroller(views);

        DrawerToggle toggle = new DrawerToggle();
        toggle.getStyle().set("margin-inline-end", "var(--vaadin-gap-s)");

        H2 viewTitle = new H2("Orders");
        viewTitle.getStyle().set("font-size", "1.125rem").set("margin", "0");

        HorizontalLayout subViews = getSecondaryNavigation();

        HorizontalLayout wrapper = new HorizontalLayout(toggle, viewTitle);
        wrapper.setAlignItems(FlexComponent.Alignment.CENTER);
        wrapper.setSpacing(false);

        VerticalLayout viewHeader = new VerticalLayout(wrapper, subViews);
        viewHeader.setPadding(false);
        viewHeader.setSpacing(false);

        addToDrawer(appTitle, scroller);
        addToNavbar(viewHeader);

        setPrimarySection(Section.DRAWER);
    }
}
```

**React** — `app-layout-secondary-navigation.tsx`

```tsx
<AppLayout primarySection="drawer">
  <h1 style={h1Style} slot="drawer">
    MyApp
  </h1>
  <Scroller slot="drawer">
    <SideNav ref={sideNavRef} style={{ margin: 'var(--vaadin-gap-s)' }}>
      <SideNavItem>
        <Icon icon="vaadin:dashboard" slot="prefix" />
        Dashboard
      </SideNavItem>

      <SideNavItem path="/orders">
        <Icon icon="vaadin:cart" slot="prefix" />
        Orders
      </SideNavItem>
    </SideNav>
  </Scroller>

  <div slot="navbar">
    <div style={{ display: 'flex', alignItems: 'center' }}>
      <DrawerToggle style={{ marginInlineEnd: 'var(--vaadin-gap-s)' }} />
      <h2 style={h2Style}>Orders</h2>
    </div>

    <HorizontalLayout
      ref={horizontalLayoutRef}
      style={{ height: '2.25rem', justifyContent: 'center', gap: '0.5rem' }}
    >
      <a href="/all" style={linkStyle}>
        All
      </a>
      <a href="/open" style={linkStyle}>
        Open
      </a>
    </HorizontalLayout>
  </div>
</AppLayout>
```

`3005EA19-8E28-4BF2-8A0A-FC3F46C04F1B`
