Blog

How to parse URL query strings

What a query string is, how URL encoding works, and how to read and build query strings with URLSearchParams or the free parser.

February 7, 2026

Someone pastes a link in Slack and it’s 600 characters long: utm_source, utm_campaign, a session ID, three filters and something called fbclid. Somewhere in there is the one parameter you need. That tail end of the URL is the query string, and it’s much less scary once you know how it’s put together.

What is a query string

A query string is everything in a URL after the ?. It holds key-value pairs joined with = and separated by &. It’s how a URL passes data to a server: search terms, page numbers, filters, tracking codes, API options.

Text
https://shop.example.com/search?q=hiking+boots&page=2&sort=price

This one has three parameters: q is “hiking boots”, page is “2” and sort is “price”. The + stands for a space. More on that shortly.

URL encoding explained

Imagine searching for “salt & pepper”. If the & went into the URL as it is, the server would think a new parameter had started. So characters with a special job in URLs, such as &, = and #, plus spaces and non-ASCII characters, get percent-encoded: replaced by % and two hexadecimal digits for each byte of the character in UTF-8.

Common encodings
Space  %20 (or + in form encoding)
&      %26
=      %3D
?      %3F
#      %23
/      %2F
@      %40
é      %C3%A9

Parsing means decoding these back to the original characters. Building means encoding every value so nothing in it is mistaken for a separator. Strictly speaking, ?, / and @ are allowed unencoded inside a query string, but encodeURIComponent() encodes them anyway, and that’s always safe.

Building query strings

You can glue a query string together with + and template literals, and it’ll work right up until a user searches for “salt & pepper”. The URLSearchParams API does the encoding for you:

JavaScript
const params = new URLSearchParams();
params.set("q", "salt & pepper grinder");
params.set("page", "1");
params.set("category", "kitchen & dining");

console.log(params.toString());
// q=salt+%26+pepper+grinder&page=1&category=kitchen+%26+dining

Each & inside a value became %26, so it can’t be read as a separator. Use set() to replace a value and append() to add another value under the same key.

Parsing query strings with URLSearchParams

The same API reads query strings too. Give it a query string, with or without the leading ?, or use the searchParams property of a URL object. Then ask for values with get(), getAll(), has() and entries():

JavaScript
const url = new URL(
  "https://shop.example.com/search?q=hiking+boots&page=2&size=9&size=10",
);
const params = url.searchParams;

console.log(params.get("q")); // "hiking boots"
console.log(params.get("page")); // "2"
console.log(params.getAll("size")); // ["9", "10"]
console.log(params.has("sort")); // false

for (const [key, value] of params.entries()) {
  console.log(key, "=", value);
}

Notice that size appears twice. That’s allowed, and it’s how multi-select filters and checkbox groups usually send their choices. get() returns only the first value, while getAll() returns them all. Every value comes back as a string, so "2" is not 2 until you convert it.

Common pitfalls

Spaces: plus or %20

Spaces get two spellings. In form encoding (application/x-www-form-urlencoded, used by HTML forms and URLSearchParams), a space is +. In general percent-encoding it’s %20. Both show up in real query strings, and URLSearchParams decodes both.

The trap is decodeURIComponent(). It leaves + alone, so “hiking+boots” stays “hiking+boots” and you spend twenty minutes wondering why your search results are empty.

Hash fragments

The fragment is everything after #. It isn’t part of the query string, and the browser never sends it to the server. If a URL has both, parse them separately. A URL object already splits them into its search and hash properties.

Nested objects and arrays

Query strings are flat: just keys and values. Some back ends, such as PHP and Node’s qs library, read bracket notation like filters[color]=red&filters[size]=large as nested objects. That’s a convention, not part of any URL standard. URLSearchParams sees filters[color] as an ordinary key, so you’ll need a library such as qs to get the nested structure.

How to use the query string parser

The query string parser has two modes, Parse and Build, and runs entirely in your browser.

Parse

  1. Paste a full URL or just the query part, such as page=1&sort=name, and press Parse or Enter. Anything after a # is ignored.
  2. Read the decoded parameters in the table. A repeated key gets a row for each value.
  3. Copy the JSON output, an object of keys and values, if you want it in code. If a key appears more than once, the JSON keeps only its last value.

Build

  1. Type a key and value on each row. Add parameter adds a row, and the remove button next to a row deletes it.
  2. Select Build to get a properly encoded query string, without the leading ?, and copy it.

It’s handy for debugging API calls, decoding that 600-character Slack link, or building a query string without encoding it by hand.

Need data from a webpage as JSON?

PulpMiner turns any public page into structured JSON and can save it as a live API. See it work on a demo page, no sign-up.

Try it on a demo page