Output appears here.
The URL Parser breaks any URL into protocol, host, port, path, query parameters and fragment, and pretty-prints the query string as JSON. It decodes percent-encoding, groups repeated keys into arrays and expands bracket keys like filters[brand]. Use it to read UTM links, OAuth redirects and API calls. Everything runs in your browser — nothing is uploaded.
How to parse a URL and its query string
- Paste a full URL, a URL without its scheme (
example.com/path?x=1), or just a query string (utm_source=google&utm_medium=cpc). - Keep Decode values and Expand bracket keys on for a readable breakdown, or turn them off to see parameters exactly as they were sent.
- Copy the JSON, or use Format JSON to open it in the JSON Formatter for sorting keys or further editing.
Examples
Shop search with bracket filters
Percent-encoded brackets are decoded and expanded into a nested filters object; + is read as a space; the non-default port and the fragment are kept:
https://shop.example.com:8443/search/results?q=mechanical+keyboard&sort=price_asc&filters%5Bbrand%5D=keychron&filters%5Bin_stock%5D=true&page=2&utm_source=newsletter#reviewsResult:
{
"protocol": "https",
"host": "shop.example.com",
"port": "8443",
"path": "/search/results",
"pathSegments": [
"search",
"results"
],
"query": {
"q": "mechanical keyboard",
"sort": "price_asc",
"filters": {
"brand": "keychron",
"in_stock": "true"
},
"page": "2",
"utm_source": "newsletter"
},
"fragment": "reviews"
}OAuth authorization redirect
The encoded redirect_uri and space-separated scope become readable, which makes an OAuth request easy to check:
https://auth.example.com/authorize?response_type=code&client_id=abc123&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback&scope=openid%20profile%20email&state=xyzResult:
{
"protocol": "https",
"host": "auth.example.com",
"path": "/authorize",
"pathSegments": [
"authorize"
],
"query": {
"response_type": "code",
"client_id": "abc123",
"redirect_uri": "https://app.example.com/callback",
"scope": "openid profile email",
"state": "xyz"
}
}A bare query string with repeated keys
Without a host, only the query is shown. A key that appears more than once becomes an array:
utm_source=google&utm_medium=cpc&utm_campaign=spring_sale&tag=a&tag=bResult:
{
"query": {
"utm_source": "google",
"utm_medium": "cpc",
"utm_campaign": "spring_sale",
"tag": [
"a",
"b"
]
}
}Options explained
- Decode values — decodes percent-escapes such as
%3Aand%20and reads+as a space in keys, values, path and fragment. Turn it off to see the raw, still-encoded text, for example when debugging double encoding. - Expand bracket keys (a[b]=1) — turns
filters[brand]=xinto a nested object andids[]=1&ids[]=2into an array, as PHP, Rails and theqslibrary do. Turn it off to keepids[]as a literal key.
With both off, ?tags[]=js&tags[]=css&q=a%2Bb+c gives "tags[]": ["js", "css"] and "q": "a%2Bb+c"; with both on, "tags": ["js", "css"] and "q": "a+b c".
Common URL parsing problems
"This is not a valid URL."
The text could not be read as a URL — often an unclosed IPv6 bracket, a stray character in the host, or several URLs pasted together. Paste one URL at a time, in the form https://host/path?key=value.
A plus sign turned into a space
In query strings, + means a space (form encoding). A literal plus must be sent as %2B. If the original system meant +, the sender did not encode it; turn off Decode values to see what was really sent.
A value still contains % sequences
The escape is malformed, such as %E0%A4 cut off mid-character, so it cannot be decoded and is shown as is. Or the value was encoded twice: %253A decodes to %3A. Decode it a second time by pasting it back as a query string, such as x=%3A.
The password is missing from the output
Credentials in a URL (https://user:pass@host) are a security risk. The username is shown, but the password is deliberately left out of the output.
The port disappeared
Default ports are dropped by the URL standard: https://example.com:443/ has no explicit port. Only non-default ports, like 8443, are shown.
FAQ
How do I extract query parameters from a URL?
Paste the URL; the query object lists every parameter, decoded and grouped. In JavaScript, new URL(href).searchParams.get('q') returns one value and Object.fromEntries(url.searchParams) gives a flat object, though it keeps only the last value of repeated keys and does not expand brackets.
How are repeated parameters handled?
Every occurrence is kept. tag=a&tag=b becomes "tag": ["a", "b"], and ids[]=1&ids[]=2 becomes "ids": ["1", "2"] when bracket expansion is on. A single occurrence stays a plain string, so check the type in code that consumes the output.
Can I parse UTM parameters?
Yes. Paste the tracked link and the utm_source, utm_medium, utm_campaign, utm_term and utm_content values appear in the query object, decoded. This is a quick way to confirm a campaign link was built correctly before sending it.
Why are all values strings?
A URL carries text only. page=2 and in_stock=true are the strings "2" and "true"; whether they mean a number or a boolean is up to the application. The parser does not guess, so the output matches what a server actually receives.
Is the URL sent anywhere when I parse it?
No. Parsing uses the browser's built-in URL parser inside an isolated frame that blocks network requests, and the URL is never requested. Tokens and signed links stay on your device, and nothing is stored unless you turn on "Remember my last input".
Anatomy of a URL
| Part | In the shop example | Notes |
|---|---|---|
| Protocol | https |
Missing scheme is treated as https |
| Host | shop.example.com |
Lowercased by the URL standard |
| Port | 8443 |
Omitted when it is the default (443 for https, 80 for http) |
| Path | /search/results |
Also split into pathSegments |
| Query | q=…&page=2 |
Everything after ?, before # |
| Fragment | reviews |
Never sent to the server |
Related tools
Pretty-print or reshape the output with the JSON Formatter, or turn a JSON value into an escaped string for a query parameter with JSON Escape / Unescape. More tools are under Data.