← All guides

URL Parsing and Query String Encoding — What the Browser's URL API Does for You

This tool is built entirely on the browser's native URL and URLSearchParams globals rather than a hand-rolled parser — the same objects your own code already has access to. That means every quirk below isn't this tool's behavior specifically, it's the URL specification's behavior, and it'll show up identically anywhere URLSearchParams is used.

A space becomes +, not %20

This is the single most common surprise when comparing this tool's output against encodeURIComponent. URLSearchParams encodes a space as a literal + character, following the older application/x-www-form-urlencoded convention used by HTML forms — not %20, which is what you'd get from encoding the same string with encodeURIComponent directly:

buildQueryString([{ key: "q", value: "hello world" }])
→ "q=hello+world"

encodeURIComponent("hello world")
→ "hello%20world"

Both are valid, standards-compliant encodings of the same space character — a server reading the query string will decode + back to a space correctly, because + in a query string has no other meaning. But if you're comparing this tool's output character-for-character against output from a different encoder, this is the one difference that will look like a bug and isn't.

A bare domain isn't a valid URL — the scheme is required

Advertisement

new URL() throws on anything that isn't a complete, absolute URL. example.com/path and /path both get rejected, even though they look like reasonable input, because neither includes a scheme (https://). This isn't a limitation this tool adds on top — it's the same constraint every browser's URL constructor enforces, since a relative reference genuinely can't be resolved into protocol/host/port without a base URL to resolve it against.

Default ports come back empty, not 80 or 443

Parse https://example.com/ and the port field comes back as an empty string, not "443" — the URL spec only populates port when it's explicit and non-default in the input. If your code checks port === '443' to detect HTTPS on its standard port, that check will silently fail on the overwhelming majority of real HTTPS URLs, which never write the port explicitly.

Credentials in the URL aren't surfaced in the output

A URL like https://user:pass@example.com/ parses without error — the underlying URL object exposes username and password — but this tool's output only surfaces protocol, host, port, path, query, hash, and origin. If you're debugging a URL that includes embedded credentials, this tool will parse it successfully but won't show you that part back; check the raw string itself for that piece.

Advertisement

Try the URL Parser & Query String Builder