Work in progress

Router Layouts and Nested Router Targets

For a basic routing tutorial, see Defining Routes with @Route.

RouterLayout

When defining routes using @Route("path"), the component will by default be rendered inside the <body> tag on the page (the element returned by HasElement.getElement() is attached to the <body>).

A parent layout can be defined using the Route.layout() method. As an example to have CompanyComponent render inside a layout called MainLayout the code would look like:

@Tag("div")
@Route(value="company", layout=MainLayout.class)
public class CompanyComponent extends Component {
}

All layouts used as a parent layout must implement the RouterLayout interface.

If there are multiple router target components using the same parent layout, then the parent layout instances will remain the same when the user navigates between the child components.

See also:

Multiple parent layouts with @ParentLayout

In some cases there might be a need to have a parent layout for a parent layout in the application. One example would be that we have a Main layout used for everything and a Menu bar that is reused for views.

For this we could have the following setup:

public class MainLayout extends Div implements RouterLayout {
}

@ParentLayout(MainLayout.class)
public class MenuBar extends Div implements RouterLayout {
    public MenuBar() {
        addMenuElement(TutorialView.class, "Tutorial");
        addMenuElement(IconsView.class, "Icons");
    }
    private void addMenuElement(Class<? extends Component> navigationTarget,
            String name) {
        // implementation omitted
    }
}

@Route(value = "tutorial", layout = MenuBar.class)
public class TutorialView extends Div {
}

@Route(value="icons", layout = MenuBar.class)
public class IconsView extends Div {
}

In this case we would have a MainLayout that always encapsulates MenuBar which in turn encapsulates TutorialView or IconsView depending on where we have navigated to.

In this sample we have 2 parent layers, but there is no restriction in the amount of nested layouts.

ParentLayout route control using @RoutePrefix

There might be some cases where a parent layout should supplement the navigation route by adding to the route location.

This can be done by annotating a parent layout with @RoutePrefix("prefix_to_add")

@Route(value = "path", layout = SomeParent.class)
public class PathComponent extends Div {
    // Implementation omitted
}

@RoutePrefix("some")
public class SomeParent extends Div implements RouterLayout {
    // Implementation omitted
}

In this example the route that PathComponent would receive is some/path as in the case of the previously mentioned SomePathComponent

Absolute routes

Sometimes we might have a setup where we want to use the same parent components in many parts, but in some cases not use any @RoutePrefix from the parent chain or only use them for a defined part.

In these cases we can add absolute = true to either the @Route or @RoutePrefix annotations.

So if we have something that we want to use in many places in the SomeParent layout, but do not want to get the route prefix added to our navigation path we could have a class MyContent built the following way:

@Route(value = "content", layout = SomeParent.class, absolute = true)
public class MyContent extends Div {
    // Implementation omitted
}

In this case even though the full chain path should be some/content we actually get just content as we have defined that this should be absolute.

The same works when having absolute defined in the middle of the chain for instance:

@RoutePrefix(value = "framework", absolute = true)
@ParentLayout(SomeParent.class)
public class FrameworkSite extends Div implements RouterLayout {
    // Implementation omitted
}

@Route(value = "tutorial", layout = FrameworkSite.class)
public class Tutorials extends Div {
    // Implementation omitted
}

In this case the bound route would be framework/tutorial even though the full chain is some/framework/tutorial

Note
If a parent layout has a @RoutePrefix defined the "default" child could have its route defined as @Route("") and be mapped to the parent layout route. E.g. In the case of Tutorials with route "" it would be mapped as framework/