When building dynamic web applications, it's often useful to update the URL's query parameters to reflect state changes—like pagination, filters, or search terms—without reloading the page. Thankfully, modern browsers support the History API, which lets you do this cleanly using JavaScript.

The problem

You want to update or add a query string parameter in the URL without triggering a full page reload or navigating away.

The solution

Use URL and URLSearchParams in combination with history.replaceState or history.pushState to update the browser’s address bar.

Here's a simple function to do just that:

function updateQueryStringParam(key, value) {
  const url = new URL(window.location);
  url.searchParams.set(key, value); // add or update the parameter
  window.history.replaceState({}, '', url); // update the address bar without reload
}

Example usage

updateQueryStringParam('page', '2');

If the current URL is:

https://example.com/products?category=books

After calling the function, the browser’s address bar will show:

https://example.com/products?category=books&page=2

No reload occurs, and the rest of your JavaScript app continues as normal.

When to use pushState instead

If you want the change to be recorded in the browser’s history—so users can navigate back to it with the back button—replace replaceState with pushState:

window.history.pushState({}, '', url);

Use this version when the parameter change represents a new navigable state, such as moving between pages or search results.