Skip to content

Revisiting Query String Hell

Almost eleven years ago, I wrote a blog post titled "Query String Hell". A couple years later I wrote a query string parsing library. A lot has changed in the last eleven years, and since I was rebuilding my blog I felt it was time to revisit some of my older posts that have aged less like wine and more like milk.

At the time there weren't many good references, nor tools available for client-side query string parsing. Fortunately, browsers have since adopted the URL standard, and implemented the URLSearchParams class.

So instead of writing:

const qs = QueryString.parse("foo=bar");
console.log(qs.foo); // bar

You should use:

const params = new URLSearchParams("foo=bar");
console.log(params.get("foo")); // bar

And to go from an object to a string, instead of:

console.log(QueryString.stringify({ foo: "bar" })); // foo=bar

You should use:

const params = new URLSearchParams({ foo: "bar" });
console.log(params.toString()); // foo=bar

The URLSearchParams class nicely accepts a variety of input types, allowing arrays of key-value entries, record-like object (including regular objects and Maps), and strings.

Empty keys and null values

In my original blog post I made a big fuss over some of the nuances of empty strings and null values, but none of that has been of any practical use, so don't worry about it.

That said, URLSearchParams will correctly handle a query string of = as having an empty string key with an empty string value:

const params = new URLSearchParams("=");
console.log(params.get("")); // ''

Same key multiple times

URLSearchParams also handles duplicate keys nicely by having a get method for accessing a single value (specifically: the first occurrence of a key), and a getAll method for accessing all the values:

const params = new URLSearchParams("foo=bar&foo=baz");
console.log(params.get("foo")); // bar
console.log(params.getAll("foo")); // ['bar', 'baz']

Support

URLSearchParams has been supported in all modern browsers and Node since 2017, so at this point there's no reason to use anything else for handling query strings properly.