Docs

Documentation versions (currently viewingVaadin 24)

History API

Using the History API to access and modify the browser history from the server side.

The History API allows you to access the browser navigation history from the server side. It also allows you to modify the navigation history. You can add new entries or change the current entry.

For example, you can change the current URL shown in the browser address bar without invoking any navigation. The history is always bound to the current browser window or frame, so you can access it through the Page object. This is available through the UI.

History history = UI.getCurrent().getPage().getHistory();

Traversing the History

With the forward(), back() and go(int) methods, you can programmatically traverse the browser’s history entries. These methods correspond to the user actions on the browser’s back and forward buttons.

history.back(); // navigates back to the previous entry

history.forward(); // navigates forward to the next entry

history.go(-2); // navigates back two entries
history.go(1); // equal to history.forward();
history.go(0); // reloads the current page

Triggering the forward(), back() and go() methods trigger asynchronously a HistoryStateChangeEvent if the history entries are for the same document (e.g., if the entries share the same origin).

Handling User Navigation

To handle manually navigation events, you can replace it by setting a handler for navigation events using history.setHistoryStateChangeHandler(HistoryStateChangeHandler). It’s notified when the user navigates back or forward using the browser buttons. It’s also notified when the navigation was done programmatically from server-side Java code or client-side JavaScript. And it’s done when the user clicks a link marked with the router-link attribute.

history.setHistoryStateChangeHandler(this::onHistoryStateChange);

private void onHistoryStateChange(HistoryStateChangeEvent event) {
    // site base url is www.abc.com/
    // user navigates back from abc.com/dashboard to abc.com/home
    event.getLocation().getPath(); // returns "home"
}

The server-side history state-change event isn’t fired, though, if only the hash has changed. Hash is always stripped from the location sent to the server. It’s a browser feature not intended for use on the server side.

Changing History

You can update the history by either pushing new entries to the history, or by replacing the current entry. You may provide a JSON value as the state parameter. This state value is available via LocationChangeEvent:getState() when the entry next visited.

history.pushState(null, "home");

JsonValue state = Json.create("preview-mode");
history.replaceState(state, "about");

The first line here adds a new history entry for the location "home" with no state. The second and third lines replace the current entry with location "about" and a state object.

The URL used with pushState() and replaceState() must be for the same origin as the current URL. Otherwise, the browser throws an exception and the history isn’t updated.

If you use either pushState() or replaceState(), the framework internal scroll position restoration on navigation won’t work. This is because it stores data in the history.state to keep track of the scroll position.

For cases where the new pushed or replaced URL needs to be available on the server, there are overloaded methods with callback. Setting callback to true will generate a history event on the server when using a pushState or replaceState.

This could be useful when changing query parameters so the server would be updated without the need to get the URL from the client by using fetchCurrentURL in Page. Callback only works, though, when using the react-router.

CDD7DD56-9749-4F4C-9126-9C984B65B066