Why take a URL apart
Long URLs hide most of what they carry. A marketing link holds half a dozen utm_ parameters, an OAuth callback carries an encoded code and state, and a redirect parameter often contains a whole second URL, percent-encoded so that its own ? and & do not collide with the outer query. Reading that by eye means mentally decoding %2F, %3F and %26 while counting ampersands. The URL parser does it for you and lays the result out as a labelled list.
Each URL is validated by the WHATWG URL parser, the same algorithm browsers, Node and Deno use, with URLSearchParams-style query splitting. If the browser would reject the URL, so does this page, and it tells you which part is broken.
What the breakdown shows
For an absolute URL you get:
- Scheme and, when present, Username and Password. Passwords are masked as
****in the output and trigger a warning, because URLs with credentials end up in logs and browser history. - Host, labelled as an IPv4 or IPv6 address where relevant. Internationalised domain names are shown in Unicode with the Punycode form (
xn--...) underneath. - Port, including the implicit default, such as
443 (default for https). An explicit port equal to the default is pointed out as removable. - Path as written, then each Segment decoded on its own line.
- Query, one parameter per line with the key and its decoded value aligned. A key that appears three times is listed three times, in order, which is how most frameworks build arrays such as
tags=red&tags=blue. Keys without=are shown as flags. - Fragment, decoded.
The Table view puts each part in three columns, Part, Raw and Decoded, which makes it easy to see exactly which characters were encoded. Copy any of it with Ctrl/Cmd+Shift+C. There are no options to set: the format has one correct reading.
Inputs it accepts besides full URLs
A bare query string such as page=2&sort=price_asc, with or without the leading ?, is parsed as parameters only. A path beginning with / is treated as a relative URL, and a protocol-relative //cdn.example.com/app.js is validated as if it had a scheme. Paste several lines to compare URLs side by side, for instance the link you sent and the one the server logged.
Something like shop.example.com/search is rejected because without a scheme it is not a URL at all, only a path; the hint suggests the https:// version. Nothing you paste leaves the browser, which is useful when the query contains session IDs or one-time codes.
Decoding rules and edge cases
In query strings a + means a space, following the form-encoding rules browsers use, while in paths a + stays a plus. Percent-decoding is lenient: one malformed sequence such as a lone % in 100% produces a warning and that value is shown as written, instead of failing the whole URL. Literal spaces are reported too, since they should be %20 or +. Ports above 65535 and hosts containing spaces or invalid IPv4 numbers are errors with the column of the offending character.
Examples
Campaign link with a nested redirect
The redirect parameter decodes to its own path and query, so you can read the coupon code without decoding it by hand.
https://www.example.com/landing?utm_source=newsletter&utm_medium=email&utm_campaign=sept-sale&redirect=%2Fcheckout%3Fcart%3D8f2k1%26coupon%3DSEPT10https://www.example.com/landing?utm_source=newsletter&utm_medium=email&utm_campaign=sept-sale&redirect=%2Fcheckout%3Fcart%3D8f2k1%26coupon%3DSEPT10
Scheme https
Host www.example.com
Port 443 (default for https)
Path /landing
Segments 1. landing
Query 4 parameters
utm_source = newsletter
utm_medium = email
utm_campaign = sept-sale
redirect = /checkout?cart=8f2k1&coupon=SEPT10
Bare query string with repeated keys
Each tags value is listed separately, and the + signs and UTF-8 escapes in q decode to “café crème”.
tags=red&tags=blue&tags=green&sort=-created_at&q=caf%C3%A9+cr%C3%A8meQuery string
Query 5 parameters
tags = red
tags = blue
tags = green
sort = -created_at
q = café crème
OAuth callback and a database URL
Two lines give two reports; the database password is masked in the output and flagged with a warning.
https://app.example.com/oauth/callback?code=4%2F0AfJohXk&state=xyz123&scope=openid%20email%20profile
https://admin:[email protected]:5432/ordershttps://app.example.com/oauth/callback?code=4%2F0AfJohXk&state=xyz123&scope=openid%20email%20profile
Scheme https
Host app.example.com
Port 443 (default for https)
Path /oauth/callback
Segments 1. oauth
2. callback
Query 3 parameters
code = 4/0AfJohXk
state = xyz123
scope = openid email profile
https://admin:****@db.internal.example.com:5432/orders
Scheme https
Username admin
Password ****
Host db.internal.example.com
Port 5432
Path /orders
Segments 1. orders
Common errors and how to fix them
| Error | Cause | Fix |
|---|---|---|
This line is not a URL: it has no scheme such as https:// | The text is a host and path without a scheme, or contains a space before the colon, so it is neither a URL nor a query string. | Add the scheme, for example https://shop.example.com/search. To parse only parameters, paste the part after the ?. |
Malformed percent-encoding "%" in query parameter "q"; shown as written | A % is not followed by two hex digits, or the escapes do not form valid UTF-8. Browsers usually pass such values through unchanged. | Encode a literal percent sign as %25 when building the URL, for example with encodeURIComponent. |
The port 99999 is out of range 0–65535 | Ports are 16-bit numbers, so anything above 65535 makes the URL invalid in every browser. | Correct the port number, or remove it to use the default for the scheme. |
The URL contains a password; avoid sharing or logging it | The URL has user:password@ before the host. It still parses, but the credential is exposed wherever the URL is stored. | Move the credentials to an environment variable or an Authorization header, and rotate the password if the URL was shared. |
Frequently asked questions
How do I decode a URL-encoded string?
Paste the full URL or just the query string. Every parameter value is percent-decoded in the output, and the Table view shows the raw and decoded forms next to each other.
Why does + turn into a space in some values but not others?
Form encoding treats + as a space only in the query string. In the path a + is a literal plus sign, so it is left alone there.
Can it handle repeated query parameters?
Yes. Every occurrence is listed in its original order, so a=1&a=2 shows two lines. How your server combines them into an array or keeps only one value depends on the framework.
Does it support internationalised domain names?
Yes. A host such as münchen.example is shown in Unicode together with its Punycode form xn–mnchen-3ya.example, which is what DNS actually resolves.