Docs

Documentation versions (currently viewingVaadin 24)

Add a View

In this guide, you’ll learn how to create and name views in Java, assign multiple routes to a single view, and organize views into Java packages. To reinforce your learning, a hands-on mini-tutorial at the end helps you apply these concepts in a real Vaadin application.

Creating Views

Flow views are Java classes that are annotated with @Route and extend com.vaadin.flow.component.Component — or any of its subclasses. The default parameter of the @Route annotation is the path of the view.

For example, you can define the HelloWorld component as the root view like this:

@Route("")
public class HelloWorld extends Div {
    public HelloWorld() {
        setText("Hello world");
    }
}

If the application is running from the root context, users would be able to access this view by navigating to https://example.com.

Likewise, you can define the CustomerListView component as the target for the customer/list route:

@Route("customer/list")
public class CustomerListView extends Main {
    public CustomerListView() {
        //...
    }
}

Users would be able to access this view by navigating to https://example.com/customer/list.

Note
Don’t include a leading / when you specify the path of a view.

Navigation between views is covered in more detail in the Navigate to a View guide.

View Naming

If you do not specify a default parameter for @Route, the path is derived from the name of the view. The derived name is the class name in lower case, with the View suffix removed if there is one. Also, MainView and Main are mapped to root.

For example:

  • MyEditor becomes "myeditor"

  • PersonView becomes "person"

  • MainView becomes ""

If you specify the path explicitly, you can name your views any way you like.

Route Aliases

You can create multiple routes that target the same view. You do this with the @RouteAlias annotation.

For example, you can map https://example.com, https://example.com/home, and https://example.com/main to HomeView like this:

@Route("")
@RouteAlias("home")
@RouteAlias("main")
public class HomeView extends Div {
    public HomeView() {
        //...
    }
}

Whenever you use route aliases, you have to create a primary route by using the @Route annotation. Only adding @RouteAlias to a view does not work.

Page Title

By default, Flow views do not set a page title. You can define the page title either declaratively or dynamically.

Declarative Page Title

To set a page title declaratively, use the @PageTitle annotation:

@Route("")
@PageTitle("Home Page")
public class HomeView extends Div {
    public HomeView() {
        //...
    }
}

Dynamic Page Title

To set the page title dynamically, implement the HasDynamicTitle interface:

@Route("")
public class HomeView extends Div implements HasDynamicTitle {

    public HomeView() {
        //...
    }

    @Override
    public String getPageTitle() {
        return "Home Page";
    }
}

The title is determined when the router navigates to the view. Any changes made after navigation will not affect the title.

Important
A view cannot use both the @PageTitle annotation and implement the HasDynamicTitle interface simultaneously.

Most business applications include a navigation menu. This menu can be generated dynamically using Vaadin’s MenuConfiguration. To make a Flow view appear in the menu, add the @Menu annotation:

@Route()
@Menu(title = "Dashboard", order = 1, icon = "vaadin:dashboard")
public class DashboardView extends Main {
    public DashboardView() {
        //...
    }
}

The @Menu annotation has the following attributes:

title

The menu title. Defaults to the page title if not specified.

order

Determines the menu item’s position. Items with a defined order appear above unordered items.

icon

Specifies the menu icon. This is a string, allowing flexibility in interpretation. It could be an Icon name or an SVG source, depending on the menu implementation.

For more information on building a navigation menu, see Add a Router Layout.

Package Naming

The recommended naming convention for Java packages containing views is [feature].ui.view, where [feature] is the name of the full-stack feature that the view belongs to.

If the view consists of a single class only, you can store it directly in the ui.view package, like this:

com.example.application
└── crm (1)
    └── ui
        └── view
            ├── CustomerOnboardingView.java (2)
            ├── CustomerListView.java
            └── CUstomerDetailsView.java
  1. The example feature is "customer relationship management".

  2. All the views are in the same ui.view package.

If the view consists of more than one class, consider creating a separate package for it, like this:

com.example.application
└── crm
    └── ui
        └── view
            ├── onboarding
            │   ├── CustomerOnboardingView.java (1)
            │   └── ...
            ├── CustomerListView.java (2)
            └── CustomerDetailsView.java
  1. The onboarding view consists of multiple classes and has its own package.

  2. The other views remain in the ui.view package.

If you don’t know whether your new view is going to be small or large, start by putting it in the ui.view package. You can always refactor it into its own package later.

Try It

In this mini-tutorial, you’ll explore both derived and explicit routes. You’ll also create a new, simple view and specify multiple routes for it.

Set Up the Project

First, generate a walking skeleton with a Flow UI, open it in your IDE, and run it with hotswap enabled.

Modify the Todo View

You’ll start by changing the path of the TodoView to todo. Open the class TodoView in the [application package].todo.ui.view package. Find the @Route annotation on the class, and remove the default parameter value. The code should now look like this:

@Route 1
@PageTitle("Task List")
@Menu(order = 0, icon = "vaadin:clipboard-check", title = "Task List")
public class TodoView extends Main {
    ...
}
  1. The "" default parameter value has been removed.

Because the path is now derived from the name of the class, you can access the view at: http://localhost:8080/todo

Create a Main View

Next, you’ll create a new main view. Create a new package [application package].tutorial.ui.view, and inside it a new class called MainView, like this:

import com.vaadin.flow.component.html.Main;
import com.vaadin.flow.router.Route;

@Route
public class MainView extends Main {
    public MainView() {
        setText("Main View");
    }
}

The path is again derived from the name of the class, which means you can access the view at: http://localhost:8080

Add a Route Alias

Now add a @RouteAlias("home") annotation to the MainView, like this:

import com.vaadin.flow.component.html.Main;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.router.RouteAlias;

@Route
@RouteAlias("home")
public class MainView extends Main {

    public MainView() {
        setText("Main View");
    }
}

You can now access the main view also at: http://localhost:8080/home

Try a Route with Multiple Segments

Now go back to TodoView and change the path to manage/tasks/with/vaadin, like this:

@Route("manage/tasks/with/vaadin")
@PageTitle("Task List")
@Menu(order = 0, icon = "vaadin:clipboard-check", title = "Task List")
public class TodoView extends Main {
    ...
}

You can now access the todo view at: http://localhost:8080/manage/tasks/with/vaadin

Final Thoughts

Now you’ve explored how to define and organize Flow views in a Vaadin application. You’ve learned how to:

  • Use both derived and explicit routes to structure your application’s navigation.

  • Create a main view and apply best practices for naming and organizing views.

  • Define multiple routes for a single view, making navigation more flexible.

  • Work with multi-segment routes to create more readable and meaningful URLs.

Next, see the Navigate to a View guide to learn how to navigate from one view to another.