> Markdown version of [Flow](https://vaadin.com/docs/v24/building-apps/views/add-view/flow). Section index: [llms.txt](https://vaadin.com/docs/v24/building-apps/llms.txt)

# Flow Views

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.

## <a id="creating-views"></a>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 main view like this:

```java
// tag::snippet[]
@Route("")
// end::snippet[]
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:

```java
// tag::snippet[]
@Route("customer/list")
// end::snippet[]
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](https://vaadin.com/docs/v24/building-apps/views/navigate.md) guide.

## <a id="view-naming"></a>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.

## <a id="route-aliases"></a>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:

```java
@Route("")
// tag::snippet[]
@RouteAlias("home")
@RouteAlias("main")
// end::snippet[]
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.

## <a id="page-title"></a>Page Title

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

### <a id="declarative-page-title"></a>Declarative Page Title

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

```java
@Route("")
// tag::snippet[]
@PageTitle("Home Page")
// end::snippet[]
public class HomeView extends Div {
    public HomeView() {
        //...
    }
}
```

### <a id="dynamic-page-title"></a>Dynamic Page Title

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

```java
@Route("")
// tag::snippet[]
public class HomeView extends Div implements HasDynamicTitle {
// end::snippet[]

    public HomeView() {
        //...
    }

// tag::snippet[]
    @Override
    public String getPageTitle() {
        return "Home Page";
    }
// end::snippet[]
}
```

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.

## <a id="navigation-menu-item"></a>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:

```java
@Route()
// tag::snippet[]
@Menu(title = "Dashboard", order = 1, icon = "vaadin:dashboard")
// end::snippet[]
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](https://vaadin.com/docs/v24/components/icons.md) name or an SVG source, depending on the menu implementation.

For more information on building a navigation menu, see [Add a Router Layout](https://vaadin.com/docs/v24/building-apps/views/add-router-layout/flow.md#the-navigation-menu).

## <a id="package-naming"></a>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.

## <a id="try-it"></a>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

To start, generate a [walking skeleton with a Flow UI](https://vaadin.com/docs/v24/getting-started/start.md), [open](https://vaadin.com/docs/v24/getting-started/import.md) it in your IDE, and [run](https://vaadin.com/docs/v24/getting-started/run.md) it with hotswap enabled.

Create a Dashboard View

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

DashboardView\.java

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

@Route
public class DashboardView extends Main {
    public DashboardView() {
        setText("Dashboard View");
    }
}
```

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

Delete the Main View

You’ll now make the dashboard view the default landing page of the application. To do this, you first have to delete the old main view. Locate the class `MainView` inside the package `[application package].base.ui.view` and delete it.

Add a Route Alias

Next, add a `@RouteAlias("")` annotation to `DashboardView`, like this:

DashboardView\.java

```java
import com.vaadin.flow.component.html.Main;
import com.vaadin.flow.router.Route;
// tag::snippet[]
import com.vaadin.flow.router.RouteAlias;
// end::snippet[]

@Route
// tag::snippet[]
@RouteAlias("")
// end::snippet[]
public class DashboardView extends Main {

    public MainView() {
        setText("Dashboard View");
    }
}
```

You can now access the dashboard view also at: <http://localhost:8080/>

Try a Route with Multiple Segments

Now open `TaskListView` and change the path to `manage/tasks/with/vaadin`, like this:

TaskListView\.java

```java
// tag::snippet[]
@Route("manage/tasks/with/vaadin")
// end::snippet[]
@PageTitle("Task List")
@Menu(order = 0, icon = "vaadin:clipboard-check", title = "Task List")
public class TaskListView extends Main {
    ...
}
```

You can now access the task list 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.

- 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](https://vaadin.com/docs/v24/building-apps/views/navigate.md) guide to learn how to navigate from one view to another.
