Managing Filters In the URL in React: A Practical Guide - Part 1

Written by Lucie Zdeňková on 2025-11-20

reactjavascript

In our current project, we needed to synchronize filter values with the URL in order to be able to link to filtered data. To achieve this, we used the useParams functionality from React Router. In this post, we’ll share how we built a small set of JavaScript functions that allow to read and update filter values directly in the URL.


We always try to follow the principle of a single source of truth. In this case, the source of truth for our filters is the URL itself - we write to it and read from it, instead of duplicating the state elsewhere.

To illustrate the idea, we’ll start with a simple full-text filter, where the filter value is just a string.

1. Reading a Filter Value from the URL

The first function extracts a filter value from the query string. Using params.getAll(key) ensures we correctly read all values of the given parameter.

function extract_field_from_params(params, key, defval = "") {
    const vals = params.getAll(key);
    const val = vals.length === 0 ? defval : vals[0];
    return val;
}

2. Updating a Filter Value in the URL

To update the filter, we create a new instance of the URLSearchParams object. From there, we remove the existing value using newParams.delete(key) and then we add the new value using newParams.append(key, value).

function set_field_to_params(params, key, val) {
    const newParams = new URLSearchParams(params);
    newParams.delete(key);
    newParams.append(key, val);
    return newParams;
}

3. Final update function

Our final function brings both operations together. It returns an array of [value, setterFunction], which intentionally reminds the familiar React hook useState.

This pattern allows us to treat URL-based filters almost exactly like regular React state variables - while keeping the URL as the single source of truth.

export function use_params_field(params, setParams, key, defval = "") {
    const val = extract_field_from_params(params, key, defval);
    const setter = (val) => {
        setParams(set_field_to_params(params, key, val));
    }
    return [val, setter];
}

4. Usage in Your Components

The usage is super simple. First call your custom use_params_field just like useState, in following one line:

const [supplierFilter, setSupplierFilter] = use_params_field(searchParams, setSearchParams, "supplier");

Second, use the setter in the input’s onChange. Usage is exactly the same as using React hook useState to manage filters. Don't forget to use the varibale supplierFilter to filter your data.

<Form.Group controlId="1">
    <Form.Label>{label}</Form.Label>
    <Form.Control
        value={supplierFilter}
        onChange={(ev) => setSupplierFilter(ev.target.value)} />
</Form.Group>

In this blog post, we went through how to update filter values in the URL using simple helper functions. We created utilities to read a parameter, update it, and implement it as a simple one-line function in the component. Wondering how to adapt these functions for multi-select or from-to filters? Then stay tuned for the next post!