Docs

Query Parameters

Learn how to manage state with query parameters in Vaadin.

In this guide, you’ll learn how to read and set query parameters in a Vaadin view, and how to bind a field to a query parameter with a signal so the two stay in sync.

Copy-Paste into Your Project

If you want to quickly try out query parameters in your Vaadin application, copy-paste the following code into a new Java class named QueryParameterView in your project’s main package:

Source code
QueryParameterView.java

This view reads the filter query parameter from the router state signal and two-way binds it to a text field: the field shows the current value, and editing it updates the URL. For more detailed instructions on how to use query parameters, continue reading below.

What Are Query Parameters?

Query parameters are key-value pairs appended to the end of a URL after a ? character. Multiple parameters are separated by &.

For example, this URL: /orders?sort=date&filter=shipped

Contains the following query parameters:

  • sort"date"

  • filter"shipped"

Query parameters are commonly used to store view-related state, such as a grid’s sort order or a search field’s value. Since they are optional, always provide default values when a parameter is missing.

Tip
If you need required parameters, consider using route parameters instead.

Reading Query Parameters Reactively

Query parameters are part of the current location, which is available as a signal. Calling UI.getCurrentOrThrow().routerStateSignal() returns a read-only signal whose value is a RouterState record; its location() method gives you the Location, and getQueryParameters() the QueryParameters for the active navigation.

As with route templates, a convenient pattern is to derive a separate signal for each parameter. Because Signal is a functional interface, you can define one with a lambda that reads the value from the location:

Source code
Java
private static final String QUERY_PARAM_FILTER = "filter"; 1

private final Signal<String> filterParam = () -> UI.getCurrentOrThrow()
        .routerStateSignal().get().location().getQueryParameters()
        .getSingleParameter(QUERY_PARAM_FILTER).orElse("");
  1. Tip: To improve readability and maintainability, declare query parameter names as constants.

Bind components to these parameter signals as you would to any other signal. Reading the value inside a binding’s reactive context makes the component update automatically whenever the parameter changes.

The QueryParameters class provides methods for accessing query parameter values; familiarize yourself with its API if you use query parameters often. Since query parameters are always strings and always optional, they may be missing or contain invalid data, so always supply a default with orElse() and validate as needed.

Note
If you need to inspect query parameters imperatively — for example, to redirect before the view renders — implement BeforeEnterObserver and read event.getLocation().getQueryParameters() inside beforeEnter().

Setting Query Parameters

The QueryParameters class is immutable, meaning you can’t modify existing query parameters. Instead, you must create a new QueryParameters object and pass it to UI.navigate(). Query parameters are set when navigating to a view.

In the following example, OrdersView provides a custom API for navigating to itself while setting the filter query parameter:

Source code
Java
@Route
public class OrdersView extends Main implements BeforeEnterObserver {

    private static final String QUERY_PARAM_SORT = "sort";
    private static final String QUERY_PARAM_FILTER = "filter";

    public static void showOrders(@Nullable String filter) {
        var queryParameters = filter == null ? QueryParameters.empty()
            : QueryParameters.of(QUERY_PARAM_FILTER, filter);
        UI.getCurrent().navigate(OrdersView.class, queryParameters);
    }
    ...
}
Important
You cannot set query parameters to null. To clear a query parameter, exclude it from the QueryParameters object.

Binding a Field to a Query Parameter

Query parameters often back a form field directly — a filter, a search term, or a sort option. With the parameter exposed as a signal, you can two-way bind a field to it using bindValue(): the field shows the current value, and edits write back to the URL.

Source code
Java
filterField.bindValue(filterParam, this::setFilter); 1

private void setFilter(String filter) {
    var queryParameters = UI.getCurrent().getActiveViewLocation()
            .getQueryParameters()
            .merging(QUERY_PARAM_FILTER, filter); 2
    UI.getCurrent().navigate(QueryParameterView.class, queryParameters);
}
  1. filterParam is the parameter signal from Reading Query Parameters Reactively; setFilter() is called whenever the field changes.

  2. merging() replaces only the filter parameter and leaves any others in the URL intact.

When the user edits the field, setFilter() navigates the view to itself with the updated query parameters. The existing view instance is reused, the browser URL updates, and the router state signal — and therefore the bound field — reflects the new value. The binding works in both directions, so the field also updates if the URL changes by other means, such as the browser’s back button.

merging() preserves the other parameters: if the URL was /orders?sort=date&filter=shipped and the user enters "foobar", it becomes /orders?sort=date&filter=foobar.

Updated