Vaadin 14 Nested Route avoid Refresh on navigate

Everytime I click on the “Add”-Button in the OperationsLayoutFactory, the Page is refreshed and empty after that.

I only want to insert the “textfieldName” into the Div in page1 of the tabs.

I can click Back in the Browser when i see the empty page. After that, its added correctly.

How can I avoid the loading of the new, empty page? Is there something wrong with my Routes?

Before Add-Click
[![Before “Add”-Click]

After Add-Click and Browser-Back
[![After Add-Click and Browser-Back]

**My Route Layout**
--OperationsLayout (Route Name: Operations), Parent: UniversMainUI
---AddUniversitaetLayout (Route Name: justtest), Parent: OperationsLayoutFactory


@PageTitle("U N I V E R S")
@Theme(value = Lumo.class, variant = Lumo.DARK)
public class UniversMainUI extends Composite<VerticalLayout> implements HasComponents, RouterLayout {

private UniversLogoLayoutFactory universLogoLayoutFactory;

private UniversMenuFactory universMenuFactory;

Component logo;
Component menueLinks;
Component rechtsDatenfeld;
Component studentRemove;

private Div childWrapper = new Div();

public UniversMainUI() {


@PostConstruct // autowired-Components sind erst nach Konstruktordurchlauf verfuegbar
private void init() {

	logo = universLogoLayoutFactory.createComponent();

	menueLinks = universMenuFactory.createComponent();

	Stream<Component> children = menueLinks.getChildren();
	List<Component> listchildren = children.collect(Collectors.toList());
	ArrayList<Component> arraylistchildren = new ArrayList<Component>(listchildren);

	HorizontalLayout h1 = new HorizontalLayout(menueLinks, childWrapper);
	getContent().setSizeFull(); // wichtig fuer Ermoeglichung prozentualer Angabe der Komponentenausmasse

	for (Component c : arraylistchildren) {
		if (c.getId().get().equals("menueTreeGrid")) // auf Werte vom Typ Optional kann mittels name.get zugegriffen werden
			TreeGrid<Ebene> myTreeGrid = (TreeGrid<Ebene>) arraylistchildren.get(0);
			myTreeGrid.addItemClickListener(event -> {
				if (event.getItem().getBezeichnung().equals(LangStrings.MENU_ADD_STUDENT.toString())) {
					myTreeGrid.getUI().ifPresent(ui -> ui.navigate("StudentLayout"));
				if (event.getItem().getBezeichnung().equals(LangStrings.MENU_REMOVE_STUDENT.toString())) {
					myTreeGrid.getUI().ifPresent(ui -> ui.navigate("DeleteStudent"));
				if (event.getItem().getBezeichnung().equals(LangStrings.MENU_OPERATIONS.toString())) {
					myTreeGrid.getUI().ifPresent(ui -> ui.navigate("Operations"));


public void showRouterLayoutContent(HasElement content) {


@org.springframework.stereotype.Component // spring-Component und NICHT vaadin-component (aufpassen bei Import)
public class OperationsLayoutFactory extends Composite<VerticalLayout> implements 
UIComponentBuilder,RouterLayout {
AddUniversitaetLayoutFactory addUniversitaetLayoutFactory;
Div childChildWrapper=new Div();

@Route(value = "Operations", layout = UniversMainUI.class)
private class OperationsLayout extends VerticalLayout {
	Tab tab1;
	Tab tab2;
	Tab tab3;
	Div page1;
	Div page2;
	Div page3;
	Map<Tab, Component> tabsToPages;
	Tabs tabs;
	Div pages;
	Button addButton;

	public OperationsLayout() {

	public OperationsLayout init() {
		tab1 = new Tab("Hinzufuegen");
		tab2 = new Tab("Alle Anzeigen");
		tab3 = new Tab("Statistiken");

		page1 = new Div();
		page2 = new Div();
		page3 = new Div();


		tabsToPages = new HashMap<>();

		tabs = new Tabs(tab1, tab2, tab3);
		pages = new Div(page1, page2, page3);
		addButton=new Button("Add");
		addButton.addClickListener(e -> {
			page1.getUI().ifPresent(ui -> ui.navigate("justtest"));

		return this;

	public OperationsLayout layout() {

		page1.setText("Erste Seite");

		page2.setText("Zweite Seite");

		page3.setText("Dritte Seite");

		tabsToPages.put(tab1, page1);
		tabsToPages.put(tab2, page2);
		tabsToPages.put(tab3, page3);

		pages.setWidth("100%"); // Nutzung verfuegbarer Breite fuer Tabinhalte

		Set<Component> gezeigteSeiten = Stream.of(page1).collect(Collectors.toSet());

		tabs.addSelectedChangeListener(event -> {
			gezeigteSeiten.forEach(page -> page.setVisible(false));
			Component ausgewaehlteSeite = tabsToPages.get(tabs.getSelectedTab());

		HorizontalLayout h1=new HorizontalLayout();
		return this;


public com.vaadin.flow.component.Component createComponent() {

	return new OperationsLayout().init().layout();


public void showRouterLayoutContent(HasElement content) {
	System.out.println("zu childchildwrapper: "+childChildWrapper.getElement()+" wird jetzt hinzugefuegt: "+content.getElement());


@org.springframework.stereotype.Component // spring-Component und NICHT vaadin-component (aufpassen bei Import)
public class justTest extends Composite<VerticalLayout> implements UIComponentBuilder {	//TODO: Listener einbauen

@Route(value="justtest", layout=OperationsLayoutFactory.class)
private class AddUniversitaetLayout extends Composite<VerticalLayout>{
	TextField textfieldName;
	public AddUniversitaetLayout() {
		// TODO Auto-generated constructor stub

	public AddUniversitaetLayout init() {

		textfieldName=new TextField("Test erfolgreich!");
		return this;

	public AddUniversitaetLayout bind() {
		return this;

	public AddUniversitaetLayout layout() {
		return this;



public com.vaadin.flow.component.Component createComponent() {
	return new AddUniversitaetLayout().init().bind().layout();


Push :slight_smile:

I did not read your code, but FYI:

Try @PreserveOnRefresh

To survive a click on the web browser’s Reload button, you must use the @PreserveOnRefresh annotation. You may need to do so as well for the browser’s Back button. I’m not sure, but you can give it a try. See item # 6 here:

When trying this annotation, be careful to read the Preconditions and Limitations listed at end of [page in the manual]
( This annotation does not preserve the UI instance, as that is quite often replaced/reinitialized. See [Issue # 6,321]
( for some discussion.

Each route invocation loads a new view

As for the routing, I am not familiar with [nested routing]
( But I know for top-level URL in browser address bar, the use of a Route does indeed load a fresh view each time. My understanding is that this behavior is an intentional feature, and not a bug.

The [documentation talks]
( about the BeforeLeaveEvent as a way to handle this departure where user might lose data:

A typical use case for this event is to ask the user whether they want to save any unsaved changes before navigating to another part of the application.