URL Parser Online: Split a URL into Protocol, Host, Path, Query Parameters and Hash
Paste a URL and the parser splits it into its components: protocol, origin, host, hostname, port, path, every query parameter as a decoded key and value, and the fragment after `#`. It uses the same WHATWG URL parser your browser uses to follow links, so the result is exactly how Chrome, Firefox and Node.js understand the address. Use it to read long tracking links, debug OAuth callbacks and redirects, or check which UTM tags a campaign link carries.
The parts of a URL
https://user:pw@shop.example.com:8443/en/products/42?utm_source=newsletter&tag=a#reviews
└─┬─┘ └──┬──┘ └──────┬───────┘ └┬─┘└──────┬──────┘ └───────────┬──────────┘ └──┬──┘
scheme userinfo hostname port path query fragment
The origin is scheme, host and port together, https://shop.example.com:8443; browsers use it for the same-origin policy, CORS and cookies. The host includes the port when one is given; the hostname does not. The path identifies the resource on the server. The query, after ?, carries parameters. The fragment, after #, is never sent to the server: the browser keeps it to scroll to an element or for a single-page app's routing.
A port that equals the scheme's default, 443 for HTTPS or 80 for HTTP, is removed by the parser, so https://example.com:443/ shows no port. That is also why two URLs that look different can have the same origin.
Query parameters
The parser lists parameters in order as key and value pairs, already decoded: %20 and + become spaces and %C3%A9 becomes é. Repeated keys are kept separately, because many back ends read them as arrays:
?utm_source=newsletter&tag=a&tag=b&q=red+shoes
utm_source newsletter
tag a
tag b
q red shoes
How a server treats repeated keys varies. PHP keeps only the last value unless the key ends with [] (tag[]=a&tag[]=b), Express's default parser returns an array, and URLSearchParams.get() returns the first. When a parameter behaves strangely, check here whether it appears twice.
Reading UTM parameters
Campaign links carry UTM parameters that analytics tools read to attribute visits. Google Analytics uses five classic ones and added a few more for GA4:
utm_source where the traffic comes from: google, newsletter, facebook
utm_medium the channel: cpc, email, social, referral
utm_campaign the campaign name: spring_sale
utm_term the paid keyword
utm_content which link or ad variant was clicked
utm_id campaign ID, used for cost data import in GA4
Parameters are case-sensitive, so utm_source=Newsletter and utm_source=newsletter appear as two sources in reports. Paste a campaign link here to check that every tag is present, spelled consistently and correctly encoded; a campaign name with an unencoded & silently cuts the rest of the value off.
Normalisation and international domains
The WHATWG parser normalises what it reads: the scheme and host are lowercased, . and .. path segments are resolved, and international domain names are converted to their ASCII Punycode form.
new URL('HTTPS://Example.COM/a/../b').href // 'https://example.com/b'
new URL('https://münchen.de/').hostname // 'xn--mnchen-3ya.de'
new URL('/relative/path') // TypeError: Invalid URL
new URL('/relative/path', 'https://example.com/base/').href
// 'https://example.com/relative/path'
A relative path cannot be parsed on its own because it has no scheme or host. Paste a complete URL starting with https://. Punycode matters for security, too: look-alike domains using Cyrillic or Greek letters show up as xn-- hostnames here, which makes homograph phishing links easy to spot.
Parsing URLs in code
// JavaScript (browsers, Node.js, Deno, Bun)
const url = new URL(input);
url.searchParams.get('utm_source');
url.searchParams.getAll('tag'); // ['a', 'b']
# Python
from urllib.parse import urlsplit, parse_qs
parts = urlsplit(input)
parse_qs(parts.query) # {'tag': ['a', 'b'], ...}
// PHP
$parts = parse_url($input);
parse_str($parts['query'], $params);
Avoid parsing URLs with regular expressions or string splitting. Edge cases such as userinfo containing @, IPv6 hosts in brackets, encoded characters and missing paths make hand-written parsers disagree with the browser, and that disagreement is the root of many open-redirect and server-side request forgery bugs. Use the platform's URL parser and compare the parsed hostname against an allow list.
Links that carry tokens
Password-reset links, OAuth callbacks with a code parameter and magic sign-in links work as credentials for as long as they are valid. The parser only runs the browser's URL constructor on the text in this page: it does not request the address and sends nothing to a server, so it is safe to take such a link apart here.
Frequently asked questions
How do I get the query parameters from a URL?
Paste the full URL into the parser. Each parameter is listed as a decoded key and value, in order, with repeated keys kept separately.
What is the difference between host and hostname?
The hostname is the domain or IP address only. The host adds the port when the URL specifies one that is not the scheme's default, for example shop.example.com:8443.
Is the part after # sent to the server?
No. The fragment stays in the browser and is used to scroll to an element or for client-side routing. Servers and their logs never see it.
What are UTM parameters?
Query parameters such as utm_source, utm_medium and utm_campaign that analytics tools read to attribute visits to campaigns. They are case-sensitive and must be URL-encoded.
Why do I get Invalid URL?
The input is not an absolute URL, usually because the scheme is missing. Add https:// in front, or remove spaces and line breaks copied with the link.
Does the parser open the URL?
No. It only analyses the text in your browser and makes no request to the address.