What is a query string?
Every URL you type or click can have four main parts: the scheme (https://), the host (example.com), the path (/search), and the query string — the ?key=value&key2=value2 part that appears after the path. The query string is how web pages and APIs receive parameters: the search term you type, the page number you want, the sort order you select, and the tracking codes a marketing team added all live there.
You can build and decode query strings instantly with the Query String Builder. This guide explains the rules that make them work.
Why does encoding matter?
A query string is a flat sequence of characters inside a URL. Problem: URLs have a very small set of characters that are safe to use literally — the unreserved set A–Z a–z 0–9 - _ . ~. Everything else — spaces, ampersands, equals signs, Unicode characters, emoji — must be encoded before it goes into a URL, or it will be misinterpreted.
Consider this URL:
https://example.com/search?q=hello world&tag=C# programming
The space in hello world makes the URL ambiguous; many parsers will treat it as the end of the URL. The # in C# will be interpreted as a fragment delimiter. The correct encoded version is:
https://example.com/search?q=hello%20world&tag=C%23%20programming
Now the URL is unambiguous, regardless of which character set or parser reads it.
How percent-encoding works
Percent-encoding (also called URL encoding) replaces each unsafe character with % followed by its two-digit uppercase hexadecimal code point in UTF-8. The process is:
- Take the character (e.g. a space).
- Find its UTF-8 byte value (space = 0x20).
- Write
%20.
For multi-byte Unicode characters the same rule applies to each byte. The letter é is encoded as two UTF-8 bytes: 0xC3 and 0xA9, so it becomes %C3%A9.
The only characters that are never encoded are the unreserved characters: uppercase and lowercase ASCII letters, digits, and the four symbols -, _, ., ~. Everything else should be encoded to be safe.
RFC-3986 vs form encoding — what’s the difference?
There are two common encoding styles, and they differ only in how they treat spaces:
RFC-3986 (the URI standard) encodes a space as %20. This is correct for query strings in URLs you craft manually, in API requests, and in any modern HTTP client. It is what the Query String Builder uses by default.
application/x-www-form-urlencoded (HTML form encoding) encodes a space as +. This is the encoding browsers use when submitting an HTML form with method="GET". Many servers accept + as a space in query strings because of the dominance of form submissions. However, a literal + in your original data must itself be encoded as %2B to distinguish it from a space, which adds complexity.
For new code, prefer RFC-3986 (%20 spaces). Use form encoding only when interoperating with systems that explicitly expect it.
Anatomy of a query string
?page=2&q=hello+world&sort=asc&filter%5Bcolor%5D=red
│ │ │ │
│ │ │ └─ filter[color] (brackets encoded as %5B%5D)
│ │ └─────────── sort=asc
│ └───────────────────────── q=hello world (+ encoded space)
└──────────────────────────────── ? delimiter starts the query
Each key=value pair is separated by &. The ? separates the path from the query. There is no trailing delimiter required.
Common encoding pitfalls
Encoding the whole URL instead of just the value. A common mistake is to run the entire URL through an encoder, which encodes the ?, &, and = delimiters. These must stay literal; only the individual key and value strings should be encoded.
Double-encoding. If your HTTP library already encodes values, calling your own encoding on top produces %2520 (the % in %20 encoded again as %25). The result decodes to %20 instead of a space. Use the parser mode of the Query String Builder to check for double-encoding — you will see %25 in the raw column.
Forgetting non-ASCII characters. API consumers sometimes test with ASCII-only data and only discover the issue with a Japanese product name or an accented surname. Always test with Unicode values before shipping.
Using the wrong separator. While & is by far the most common separator, some older systems use ; (permitted by older HTML specs) or ,. Modern code should always use &.
Parsing a query string
Parsing is the reverse operation: take the raw key=value&key2=value2 string and decode it into structured data. The steps are:
- Strip the leading
?if present. - Strip any fragment (
#...) if present. - Split on
&to get individual segments. - For each segment, split on the first
=to separate key from value. - Decode each key and value using
decodeURIComponent(replacing+with space first if you expect form-encoded input).
The Query String Builder’s Parse mode does all of this and shows you both the raw encoded value and the decoded result, which makes it easy to spot encoding issues in URLs you paste from browser DevTools or server logs.
Duplicate keys and arrays
The URL specification does not define what happens when the same key appears more than once — ?id=1&id=2&id=3 is syntactically valid. What happens on the server side depends entirely on the framework:
- PHP (
$_GET['id']) gives you the last value:3. - Node.js
querystringgives you an array:['1','2','3']. - Python
urllib.parse.parse_qsgives you a list:['1','2','3']. - Bracket notation (
?id[]=1&id[]=2) is another convention used by PHP and some JavaScript frameworks to signal array intent.
The tool warns you when it detects duplicates so you can decide whether the repetition is intentional or a bug.
Building query strings in code
Most languages have a built-in or standard library function. Avoid string concatenation — it is easy to forget to encode a value:
JavaScript (browser/Node.js):
const params = new URLSearchParams({ q: 'hello world', page: '2' });
console.log(params.toString()); // q=hello+world&page=2
Note: URLSearchParams uses form encoding (+ for spaces). For RFC-3986 use encodeURIComponent manually.
Python:
from urllib.parse import urlencode
urlencode({'q': 'hello world', 'page': 2}) # q=hello+world&page=2
Go:
params := url.Values{"q": {"hello world"}, "page": {"2"}}
params.Encode() // q=hello+world&page=2
The Query String Builder is the fastest way to verify the output of any of these — paste the URL into Parse mode and check every value decoded correctly.
Security note: never trust query string values
Query strings are user-controlled. Any value in a query string could be crafted maliciously. Always validate and sanitise query string inputs on the server — they should never be inserted into SQL queries without parameterisation, rendered directly into HTML without escaping (XSS), or used to construct file paths without strict validation. The same escaping mindset applies when you render those values back into a page; our HTML entity encoder guide covers how to neutralise characters like <, >, and & so user input can’t break out of its context.
Summary
A query string is the ?key=value section of a URL that passes parameters to a page or API. Characters outside the safe ASCII set must be percent-encoded — spaces become %20 (RFC-3986) or + (form encoding). The Query String Builder handles encoding automatically in Build mode and decodes any URL in Parse mode, so you can verify your parameters are being transmitted exactly as intended.