Query String Parsing:
Debugging URL Parameters
Query strings carry filters, tracking codes, and auth tokens — but encoding issues and duplicate keys cause silent failures. Learn to parse query strings correctly and catch bugs before they reach production.
Every URL Tells Two Stories
A URL like https://shop.example.com/products?category=shoes&color=black&sort=price&page=2 contains two distinct layers of information. The path (/products) tells the server which resource you want. The query string (?category=shoes&color=black&sort=price&page=2) tells the server how you want it filtered, sorted, and paginated. Together they form a complete request. But when something goes wrong — a tracking parameter doesn't fire, a filter returns zero results, an OAuth redirect loses its state parameter — you need to inspect the query string in isolation. That's what a query string parser does.
URL query strings follow a precise format defined by RFC 3986: a question mark separator, followed by key=value pairs joined by ampersands. Values that contain special characters (spaces, ampersands, equals signs, non-ASCII text) must be percent-encoded. A parser's job is to reverse all of this — split on the question mark, split the remaining string on ampersands, split each pair on the first equals sign, then decode each key and value. Sounds simple. The edge cases are where parsers break.
When Query Strings Go Wrong
Empty values. The parameter ?debug has no equals sign and no value. Some systems treat this as debug=true, others as debug= (empty string), others as invalid. Google Analytics UTM parameters always have values. OAuth state parameters must have values. But there's no universal rule. A good parser handles both ?flag and ?flag=, showing you exactly what's present so you can debug accordingly.
Duplicate keys. The URL ?filter=red&filter=blue contains the same key twice. PHP's $_GET keeps only the last value (blue). Express.js with qs library parses it as an array: filter: ['red', 'blue']. Django's QueryDict preserves both with getlist(). The same URL behaves differently depending on which backend processes it. A parser that shows you all values for each key — without flattening duplicates — lets you see what's actually in the URL before your framework silently drops data.
Encoding surprises. A space can be %20 or +. Both are valid in query strings but mean different things in other parts of a URL. The + convention comes from the application/x-www-form-urlencoded format used by HTML forms. But %20 is the standard percent-encoding for spaces per RFC 3986. Most parsers handle both. Some don't. If your parser decodes + as a literal plus sign instead of a space, form-submitted data with spaces will be corrupted. Our query string parser handles both encodings correctly and shows you the decoded result.
Why the two forms exist, and how non-ASCII text becomes a run of %XX bytes, is covered in our URL encoding guide.
Real-World Debugging Scenarios
UTM parameter debugging. Your marketing team reports that Google Analytics is showing "direct / none" for traffic that should be attributed to an email campaign. The email links look correct: ?utm_source=mailchimp&utm_medium=email&utm_campaign=spring_sale. But when you parse the actual URL people click, you discover the email client is stripping query parameters from the URL. Or the campaign name contains an ampersand (spring_&_summer_sale) that breaks the parameter parsing, truncating everything after it. A quick parse of the actual URL catches this. Use our URL Encode/Decode tool to fix the encoding.
OAuth redirect debugging. OAuth flows pass critical data in query strings: ?code=abc123&state=xyz789. If the state parameter is missing or the code is URL-encoded twice (nested %253D instead of %3D), authentication breaks. Parse the redirect URL to see exactly what the provider returned before your auth library processes it. A double-encoded parameter looks correct to a human, but a parser reveals the extra layer of encoding.
Pagination and filtering. An API returns zero results, but you know there's data. Parse the query string to check if ?page=0 (should start at 1), ?limit= (empty value interpreted as 0 by a strict parser), or ?sort=price&order= (missing order defaults to ascending when you expected descending). Query string bugs are invisible in the browser address bar because the parameters look correct at a glance. Parse them explicitly to find the silent failures.
Query Strings and SEO
Search engines handle query strings carefully. Google recommends using URL parameters only for filtering and sorting content that already exists at the canonical path — never for creating new pages. A product page at /shoes with query parameters for filtering (?color=red&size=10) is fine. A different product at /products?id=123 instead of /products/123 is bad for SEO — Google can't tell whether ?id=123 and ?id=124 are the same page with different parameters or different pages entirely. Use query strings for modifiers, not identifiers.
For faceted navigation (e-commerce filters), Google recommends: use static URLs for the most important filter combinations, canonicalize less important ones to the main category page, and declare URL parameters in Google Search Console's URL Parameters tool. If your site generates thousands of near-duplicate pages from query parameter combinations, you're diluting your crawl budget and confusing search engines about which pages matter. Parse your own URLs to audit this — count how many unique parameter combinations your site generates, and block the ones that don't create unique value.