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.
|
Navigation Menu Item
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
-
The example feature is "customer relationship management".
-
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
-
The onboarding view consists of multiple classes and has its own package.
-
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 {
...
}
-
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.