Docs

Documentation versions (currently viewingVaadin 24)

Query Parameters

In this guide, you’ll learn how to access and set query parameters in a Flow view. A mini-tutorial at the end will help you apply these concepts in a real Vaadin application.

Accessing Query Parameter Values

You access query parameters similarly to multiple route parameters. Your view must implement the BeforeEnterObserver interface, which defines the beforeEnter() method. Inside this method, you can retrieve query parameters:

@Route
public class OrdersView extends Main implements BeforeEnterObserver {

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

    @Override
    public void beforeEnter(BeforeEnterEvent event) {
        event.getQueryParameters().getSingleParameter(QUERY_PARAM_SORT)
            .ifPresent(sort -> {
                // Process the sort parameter
            });
        event.getQueryParameters().getSingleParameter(QUERY_PARAM_FILTER)
            .ifPresent(filter -> {
                // Process the filter parameter
            });
    }
    ...
}
  1. Tip: To improve readability and maintainability, declare query parameter names as constants.

Now, if you navigate to /orders?sort=date&filter=shipped, the query parameter values will be:

  • sort"date"

  • filter"shipped"

The QueryParameters class provides methods for accessing query parameter values. Familiarize yourself with its API if you frequently use query parameters in your application.

Note
You can also retrieve query parameters using UI.getCurrent().getActiveViewLocation().getQueryParameters().

Since query parameters are always strings and optional, they may be empty or contain invalid data. To handle this, you can provide default values, redirect users to a different view, or display an error message.

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:

@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.

Updating Query Parameters Dynamically

Query parameters are often set dynamically, such as when users apply filters or change sort options. In such cases, the view must navigate to itself while updating query parameters.

When navigating to the same view, the existing view instance is reused. The browser URL updates, and beforeEnter() is invoked again.

The following example updates the filter query parameter when a user types in a text field:

@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 OrdersView() {
        var filterField = new TextField();
        add(filterField);

        filterField.addValueChangeListener(event -> {
            var queryParameters = UI.getCurrent().getActiveViewLocation()
                .getQueryParameters()
                .merging(QUERY_PARAM_FILTER, event.getValue());
            UI.getCurrent().navigate(OrdersView.class, queryParameters);
        });
    }
    ...
}

If the original URL was /orders?sort=date&filter=shipped, and the user enters "foobar" in the text field, the URL updates to /orders?sort=date&filter=foobar.

Try It

In this mini-tutorial, you’ll create a view that accesses and dynamically updates two query parameters.

Set Up the Project

First, generate a walking skeleton with a Flow UI, open it in your IDE, and run it with hotswap enabled.

Create the View

Create a new package [application package].tutorial.ui.view. Then, create a class named QueryParameterView:

import com.vaadin.flow.component.checkbox.Checkbox;
import com.vaadin.flow.component.html.Main;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.router.BeforeEnterEvent;
import com.vaadin.flow.router.BeforeEnterObserver;
import com.vaadin.flow.router.Route;

@Route
public class QueryParameterView extends Main implements BeforeEnterObserver {

    private static final String QUERY_PARAMETER_TEXT = "text";
    private static final String QUERY_PARAMETER_CHECK = "check";

    private final TextField textField;
    private final Checkbox checkbox;

    public QueryParameterView() {
        textField = new TextField();
        checkbox = new Checkbox();
        add(textField, checkbox);
    }

    @Override
    public void beforeEnter(BeforeEnterEvent event) {
    }
}

Open your browser and navigate to: http://localhost:8080/queryparameter

You should see an empty text field and an unchecked checkbox.

Access Query Parameters

Modify the beforeEnter() method to populate the components:

@Override
public void beforeEnter(BeforeEnterEvent event) {
    var queryParameters = event.getLocation().getQueryParameters();
    queryParameters.getSingleParameter(QUERY_PARAMETER_TEXT)
        .ifPresent(textField::setValue);
    queryParameters.getSingleParameter(QUERY_PARAMETER_CHECK)
        .map(Boolean::parseBoolean).ifPresent(checkbox::setValue);
}

The text field should now contain "hello world" and the checkbox should be checked.

Update the text Query Parameter

Modify the constructor to update the query parameter dynamically:

public QueryParameterView() {
    textField = new TextField();
    textField.setValueChangeMode(ValueChangeMode.LAZY); 1
    textField.addValueChangeListener(event -> {
        var queryParameters = UI.getCurrent().getActiveViewLocation()
            .getQueryParameters().merging(QUERY_PARAMETER_TEXT, event.getValue());
        UI.getCurrent().navigate(QueryParameterView.class, queryParameters);
    });
    checkbox = new Checkbox();
    add(textField, checkbox);
}
  1. The field updates 400 ms after the user stops typing.

Try changing the text field value in the browser. The URL updates automatically.

Update the check Query Parameter

Add a listener for the checkbox:

public QueryParameterView() {
    textField = new TextField();
    textField.setValueChangeMode(ValueChangeMode.LAZY); 1
    textField.addValueChangeListener(event -> {
        var queryParameters = UI.getCurrent().getActiveViewLocation()
            .getQueryParameters()
            .merging(QUERY_PARAMETER_TEXT, event.getValue());
        UI.getCurrent().navigate(QueryParameterView.class, queryParameters);
    });
    checkbox = new Checkbox();
    checkbox.addValueChangeListener(event -> {
        var queryParameters = UI.getCurrent().getActiveViewLocation()
            .getQueryParameters()
            .merging(QUERY_PARAMETER_CHECK, event.getValue().toString());
        UI.getCurrent().navigate(QueryParameterView.class, queryParameters);
    });
    add(textField, checkbox);
}

Try toggling the checkbox. The URL updates automatically while preserving the text parameter.

Final Thoughts

You’ve now successfully implemented query parameters in Flow. You learned how to:

  • Access query parameter values.

  • Update query parameter values dynamically.

Next, try modifying the code to:

  • Use 1 and 0 instead of true and false for the check parameter.

  • Validate the text query parameter to allow only letters, digits and whitespace.

You’re now ready to use query parameters in real Vaadin applications!