Routing and Navigation
|
This section documents the current Vaadin release line — Vaadin 24 LTS / 25.x, Java 17+, Spring Boot 3 / Jakarta EE 10 — as published at the official Vaadin documentation, which is the reference these pages are written and verified against. No specific patch version is pinned. Flow (server-side Java) is the authoring style used throughout, with Hilla / React shown where it differs; Vaadin 7 and the pre-Flow architecture appear only as migration contrast. This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production, since Vaadin ships major releases roughly twice a year and its ecosystem iterates. This section’s bibliography lists the reference material consulted while preparing these pages. |
In Flow a view is a component class annotated with @Route; the framework builds a URL-to-class map at
startup and swaps views into a layout on navigation, all server-side. This page follows
Routing & Navigation and
Views & Navigation. It replaces the Vaadin 7
Navigator / View API entirely.
Mapping views
@Route("customers") // https://.../customers
public class CustomerListView extends VerticalLayout { }
@Route(value = "", layout = MainLayout.class) // the application root
public class DashboardView extends VerticalLayout { }
@Route("about")
@RouteAlias("info") // a second path to the same view
public class AboutView extends Div { }
Omitting value derives the path from the class name (CustomerListView → customer-list). Register or
inspect routes at runtime with RouteConfiguration.
Links and programmatic navigation
add(new RouterLink("Customers", CustomerListView.class));
// from an event handler
UI.getCurrent().navigate(CustomerListView.class);
UI.getCurrent().navigate("customers/42");
RouterLink renders an <a> that Flow intercepts, so navigation stays a single round trip with no full page
load.
Route parameters
Three mechanisms, from simplest to most flexible:
// 1. A single typed parameter
@Route("customer")
public class CustomerView extends Div implements HasUrlParameter<Long> {
@Override
public void setParameter(BeforeEvent event, Long id) {
show(customerService.findById(id)); // /customer/42
}
}
// 2. Named parameters in a route template
@Route("order/:orderId/line/:lineId")
public class OrderLineView extends Div implements BeforeEnterObserver {
@Override
public void beforeEnter(BeforeEnterEvent event) {
String orderId = event.getRouteParameters().get("orderId").orElseThrow();
}
}
// 3. Query parameters
@Override
public void beforeEnter(BeforeEnterEvent event) {
QueryParameters qp = event.getLocation().getQueryParameters();
String tab = qp.getParameters().getOrDefault("tab", List.of("summary")).get(0);
}
Template segments support modifiers: :id? (optional), :path* (wildcard), and typed patterns such as
:id(\\d+). See Route
parameters.
The navigation lifecycle
Every navigation runs three phases. Observers implemented on the view — or registered globally with
UI.addBeforeEnterListener(…) — can inspect the target, redirect, or defer.
(BeforeLeaveObserver)"] leave -->|"postpone()"| pending["navigation paused
e.g. 'discard unsaved changes?'"] pending -->|"proceed()"| enter leave -->|no postpone| enter["BeforeEnter on the TARGET view
(BeforeEnterObserver)"] enter -->|"rerouteTo(...) / forwardTo(...)"| reroute["restart with a new target"] reroute --> leave enter -->|allowed| render["view attached to the layout"] render --> after["AfterNavigation
(AfterNavigationObserver) — URL is updated"] after --> done([done])
public class EditorView extends Div implements BeforeLeaveObserver {
@Override
public void beforeLeave(BeforeLeaveEvent event) {
if (binder.hasChanges()) {
BeforeLeaveEvent.ContinueNavigationAction action = event.postpone();
confirmDiscard(action::proceed);
}
}
}
// redirect an unauthenticated user
public void beforeEnter(BeforeEnterEvent event) {
if (!authenticated()) {
event.rerouteTo(LoginView.class);
}
}
rerouteTo keeps the URL; forwardTo also updates it. See
Navigation lifecycle.
Layouts
A view’s layout wraps it in a shared frame — typically an AppLayout with a navbar and drawer. A layout
class implements RouterLayout; @ParentLayout nests one layout in another. Annotating a layout with
@Layout makes it the automatic parent of every route that does not set its own.
@Layout // wraps all routes by default
public class MainLayout extends AppLayout implements RouterLayout {
public MainLayout() {
addToNavbar(new DrawerToggle(), new H1("My App"));
addToDrawer(new SideNav());
}
}
@Route(value = "reports", layout = ReportsLayout.class) // opt into a different frame
public class ReportsView extends Div { }
Page titles and error views
@Route("customers")
@PageTitle("Customers") // static <title>
public class CustomerListView extends VerticalLayout { }
@Route("customer")
public class CustomerView extends Div implements HasDynamicTitle {
@Override
public String getPageTitle() {
return customer.getName() + " — Customers";
}
}
// a 404 view
@Tag("div")
public class RouteNotFoundView extends Component
implements HasErrorParameter<NotFoundException> {
@Override
public int setErrorParameter(BeforeEnterEvent event,
ErrorParameter<NotFoundException> parameter) {
getElement().setText("No such page.");
return HttpStatusCode.NOT_FOUND.getCode();
}
}
Dynamic routes and menus
RouteConfiguration.forSessionScope().setRoute("path", View.class) registers a route for one session only — useful for feature flags or per-tenant views. MenuConfiguration.getMenuEntries() returns every route
annotated with @Menu, which pairs with SideNav to build a navigation drawer without a hand-maintained
list:
SideNav nav = new SideNav();
MenuConfiguration.getMenuEntries().forEach(entry ->
nav.addItem(new SideNavItem(entry.title(), entry.path(),
entry.icon() == null ? null : new SvgIcon(entry.icon()))));
See Retrieving routes and Side Navigation.
See also
-
Layouts —
AppLayout, the usual router layout. -
Security — guarding routes with navigation access control and
@RolesAllowed. -
Hilla and React Views — file-based routing on the Hilla side.
-
Advanced Topics —
@PreserveOnRefreshand service init listeners. -
Routing & Navigation — the official reference.