Documentation versions (currently viewingVaadin 23)
New Acceleration Kits: Observability Kit, SSO Kit, and Swing Kit. Read the blog post.

Navigating between Routes

Switching between routes/views can be initiated in two ways: programmatically using UI.navigate() methods or using links. The navigate() method is more agile for a Java programmer, as the view change can be issued from anywhere in your code and you can interact with the target view. Using links, however, is the native web way of moving from one view to another, allowing you for example to share the direct link to a specific view with your colleague, and they work even if the session has expired.

Server-Side Navigation

You can trigger navigation from the server-side code using various UI.navigate() methods.

You should primarily use UI.navigate(Class<? extends Component> navigationTarget) or navigate(Class<? extends C> navigationTarget, RouteParameters parameters) methods, where you pass the Class of the target view as a parameter. Compared to String versions, this avoids having to generate the route string manually.

In the browser, the navigate() method triggers a location update and the addition of a new history state entry, but doesn’t issue a full page reload.

Example: Navigation to the company route target when clicking a button:

Button button = new Button("Navigate to company");
button.addClickListener(e ->
     button.getUI().ifPresent(ui ->

Interacting directly with the Target View

The navigate() method where you give the target view class as a parameter returns the actual target view as Optional. This allows you to further configure the new view with its Java API.

The return value may be empty if the target view isn’t immediately available for some reason. This may happen, for example, because of security constraints or if the navigation was canceled or postponed in a navigation lifecycle events.

Example: Creating an edit button that navigates to a separate view and assigns the DTO to the target view with its Java API:

new Button("Edit " + user.getName(), event -> {
            .ifPresent(editor -> editor.editUser(user));

With this code, Vaadin doesn’t have the data to maintain a deep link to edit the same entity. For the active user of the application, a view to edit the selected entity is opened, but they can’t share a direct link to edit the same entity with their colleague. If deep linking is required, the target view must maintain enough details about the UI state in the URL, or the developer must use route parameters to pass the data, instead of the direct Java API.

Passing Data Using Route Parameters

If your target view implements HasRouteParameters, you can submit trivial data to the target view as route parameters. Compared to directly interacting with the target views Java API, this method automatically maintains the URL, which is beneficial for deep linking. However, you can’t pass more complex objects as route parameters as such, and you always need to consider data safety parameters that end up in URLs.

Example: Navigation to the user/123 route target (where "123" is the parameter) upon clicking a button:

Button editButton = new Button("Edit user details");
editButton.addClickListener(e ->
        editButton.getUI().ifPresent(ui -> ui.navigate(
                UserProfileEdit.class, "123"))

In addition to handling Route Parameters as in the above example, the UI.navigate() method has other overloads that allow you to pass Query Parameters or Route Templates Parameters to the target view.

RouterLink is a special component based on the <a> tag to create links pointing to route targets in your application.

Navigation with RouterLink fetches the content of the new component without reloading the page. The page is updated in place without a full page reload, but the URL in the browser is updated.

Example: Using RouterLink for a simple navigation target.

void buildMenu() {
    menu.add(new RouterLink("Home", HomeView.class));

@Route(value = "")
public class HomeView extends Component {

Example: Using RouterLink for navigation targets with route parameters, where the navigation target class implements HasUrlParameter.

void buildMenu() {
    menu.add(new RouterLink("Greeting",
            GreetingComponent.class, "default"));

@Route(value = "greet")
public class GreetingComponent extends Div
        implements HasUrlParameter<String> {

    public void setParameter(BeforeEvent event,
            String parameter) {
        setText(String.format("Hello, %s!", parameter));

Example: Using RouterLink for a navigation target with Route template route.

void buildMenu() {
    // user/123/edit
    menu.add(new RouterLink("Edit user details",
            UserProfileEdit.class, new RouteParameters("userID", "123")));
    // user/edit
    menu.add(new RouterLink("Edit my details",

public class UserProfileEdit extends Div implements BeforeEnterObserver {

    private String userID;

    public void beforeEnter(BeforeEnterEvent event) {
        userID = event.getRouteParameters().get("userID").
Because the parameter is defined as optional, URL links are possible both with and without the parameter.

You can use new RouterLink(viewClass) if you want to embed other elements into RouterLink without text, for example images or icons.

Example: Using RouterLink with an icon instead of text.

void buildMenu() {
    Icon vaadinIcon = new Icon(VaadinIcon.HOME);
    RouterLink link = new RouterLink(HomeView.class);

@Route(value = "")
public class HomeView extends Component {

It’s also possible to navigate with standard <a href="company"> type links. You can do that via an Anchor component to which you would supply an href and text content:

new Anchor("/hello", "Go to /hello route");

You can configure a standard link to open in a new tab by setting the anchor target attribute to _blank:

Anchor anchor = new Anchor("/hello", "Go to /hello route");
anchor.getElement().setAttribute("target", "_blank");

Vaadin router intercepts all instances of anchor navigation, and clicking on a standard link doesn’t cause a full page reload to happen by default. If you want a full page reload to happen, for example when navigating to a page that isn’t implemented using Vaadin, you can add router-ignore attribute; for example, <a router-ignore href="company">Go to the company page</a>. This can be done from the Java API as follows:

Anchor anchor = new Anchor("/hello", "Go to /hello route");
anchor.getElement().setAttribute("router-ignore", "");