Query String Parser

Parse a URL or query string into key/value pairs, edit them, and rebuild a clean query string.

Loading…

All processing runs in your browser — no files or inputs are uploaded to a server.

How to use

Paste a full URL (`https://example.com/?a=1&b=2#frag`) or a bare query string (`?a=1&b=2` or just `a=1&b=2`). The parser splits it into editable key / value rows. Add, remove, or rename pairs and the rebuilt query string updates live at the bottom. Toggle "+ for spaces" to switch between the HTML-form style (`+ = space`, what `URLSearchParams.toString()` emits) and the strict RFC 3986 style (`%20 = space`, what most modern APIs prefer).

Reach for this when debugging analytics, redirect chains, or affiliate URLs — the long mess of UTM tags, session keys, and tracking IDs becomes legible as a table. Add a missing parameter, fix a typo in a key, or drop the tracking junk before sharing a link, and copy the cleaned-up version back out. The fragment (`#…`) is stripped because it never belongs to the query layer. Everything runs in the browser via the native URL and URLSearchParams APIs, so tokens or session IDs in your link stay on your machine.

Examples

Audit an analytics URL

Input
https://shop.example.com/products?utm_source=newsletter&utm_medium=email&utm_campaign=spring_sale&product_id=42&ref=alice
Output
utm_source     newsletter
utm_medium     email
utm_campaign   spring_sale
product_id     42
ref            alice

The five-piece query string becomes a clean table you can scan and edit. To remove tracking parameters before sharing the link, delete the four `utm_*` rows and `ref`, then copy the rebuilt query — `?product_id=42` is what is left.

Repeated keys for multi-select filters

Input
?tag=react&tag=typescript&tag=performance&page=2
Output
tag    react
tag    typescript
tag    performance
page   2

Repeated keys are the standard URL convention for "this filter has multiple values" (search facets, multi-select dropdowns). Backend frameworks differ in how they expose this: Express → `req.query.tag = ["react", "typescript", "performance"]`, Rails → `params[:tag] = "performance"` (last only, unless you write `tag[]=`), Django → `request.GET.getlist('tag')`. The parser preserves order so you can audit each row.

Rebuild with strict RFC 3986 encoding

Input
query (raw): q=hello world&lang=ko
plusForSpaces: off
Output
q=hello%20world&lang=ko

With "+ for spaces" off, spaces become `%20` and the result matches the `application/x-www-form-urlencoded` strict variant. Use this when you need predictable encoding across mixed clients — some backends (older PHP, certain Java servlets) decode `+` correctly only for form bodies, not query strings.

FAQ

`+` vs `%20` — which should I use?

Both are valid in a query string, but they come from different specs. `%20` is the universal RFC 3986 percent-encoding for a space and works everywhere. `+` is the `application/x-www-form-urlencoded` convention (originally a 1990s HTML-form thing) and works in most query parsers but is technically only required for form bodies. Modern advice: emit `%20` if you control both ends, accept either on the receive side. JavaScript's `URLSearchParams.toString()` always emits `+`, which is why so many manual implementations exist.

How are arrays / multiple values represented in URLs?

Four conventions exist, none of them universal. **Repeated keys** (`?tag=a&tag=b`) is the most portable and what this tool produces — every parser handles it. **Bracket notation** (`?tag[]=a&tag[]=b`) is the PHP convention; Rails copied it. **Indexed** (`?tag[0]=a&tag[1]=b`) is rare but used by some Rails forms. **Comma-separated** (`?tag=a,b`) is what OpenAPI 3 `style: form, explode: false` produces. Pick the style your server expects; mixing them in one URL is a bug.

Does the tool keep the URL path and fragment?

No — it isolates the query layer only. Pasting a full URL extracts the query, drops the scheme, host, path, and fragment, and rebuilds only the `key=value&…` portion. To paste-edit-rebuild a full URL, copy the rebuilt query and concatenate it manually onto your path (`/products?` + result), or use a URL-parsing tool that exposes all the URL components.

Why does an empty value disappear?

It does not — the tool keeps `key=` rows when the value is empty. But entirely empty *keys* are dropped on rebuild, because `=value` without a key has no defined semantics in any major parser. If you need a row for "the value of `flag` is the empty string", set the key and leave the value cell blank. If you need a row for "the parameter `flag` is present with no value at all" — also leave value blank; many parsers treat both equivalently.

Is the key order preserved on rebuild?

Yes — the editor preserves insertion order and the rebuild walks rows top-to-bottom. RFC 3986 does not require any specific order, so most servers treat `?a=1&b=2` and `?b=2&a=1` identically. But for caching layers (CDN cache keys), webhook signature verification, and human review, stable order is usually preferred. AWS Signature v4 and OAuth 1.0a both explicitly sort the parameters before signing — if you are matching such a signature, sort the rows before copying out.

Difference between this and the URL Encoder tool?

URL Encoder operates on a single string — encode it or decode it as one blob. Query String Parser operates on the *structure* — split into key / value rows, edit, rebuild. Use URL Encoder when you need to escape a single value (a redirect target, a token) before pasting into a URL. Use this tool when the input is a whole query string and you want to inspect or modify individual parameters.

Related concepts

A URL query string is the portion after `?` and before `#`, defined by RFC 3986 §3.4 as an opaque sequence of bytes. The "key=value pair separated by `&`" convention is *not* in the URI spec — it comes from HTML form submissions and the `application/x-www-form-urlencoded` media type. Most servers and browsers default to the form convention, but the URI spec does not require it, which is why every framework still ships its own query parser with subtly different edge cases.

The big variation is **encoding for spaces**. Form-urlencoded uses `+`; RFC 3986 percent-encoding uses `%20`. `URLSearchParams.toString()` emits `+`, the WHATWG URL Standard requires it, and most browsers follow. `encodeURIComponent` emits `%20`. The receiving side typically accepts both; the sending side picks one. Watch out when signing requests — AWS Signature v4 requires `%20`, OAuth 1.0a requires `%20`, and emitting `+` will fail signature verification silently.

Four adjacent concepts hover around the query string. **Hash fragments** (`#…`) are *not* sent to the server; they exist only in the browser and are used by single-page apps for client-side routing — confusingly, some old code parses query parameters out of the fragment too (`#?a=1`). **Form encoding** (the `application/x-www-form-urlencoded` POST body) is the same syntax as the query string, just in the body — so the same parser works for both. **Cookie parsing** has different rules entirely (`;` separators, no percent-encoding by default). **JSON request bodies** replaced query strings for most POST / PUT APIs around 2010, but query strings stayed dominant for GET because they are bookmarkable, cacheable, and copy-pasteable in a way bodies are not.

Related tools