Navigating between Routes
Switching between routes or views can be initiated in two ways: programmatically using UI.navigate()
methods; or by 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 a 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 ->
ui.navigate("company"))
);
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 -> {
ui.navigate(UserEditor.class)
.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 HasUrlParameter
, 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.
Using the RouterLink Component
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> {
@Override
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",
UserProfileEdit.class));
}
@Route("user/:userID?/edit")
public class UserProfileEdit extends Div implements BeforeEnterObserver {
private String userID;
@Override
public void beforeEnter(BeforeEnterEvent event) {
userID = event.getRouteParameters().get("userID").
orElse(CurrentUser.get().getUserID());
}
}
Note
| 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);
link.add(vaadinIcon);
menu.add(link);
}
@Route(value = "")
public class HomeView extends Component {
}
Using Standard Links
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", "");
3F7CDDD8-C4FB-44DC-9047-C48EAB57C862