URL Parser

Paste a URL and see it split into scheme, host, port, path, query and fragment. Use it when a route will not match and you need to see what a URL parser reads, instead of what you think you typed. The tool uses the browser's built-in URL API, the same parser Node.js ships.

Input URL
Parsed Components

Enter a URL to parse its components

1 A URL has four main parts

  • Protocol: The scheme, such as https or ftp. The parser needs it to read the rest.
  • Host: The domain name or IP address, such as example.com.
  • Path: The location of the resource on that host, such as /api/v1/users.
  • Query: Key-value parameters sent to the server, such as ?id=123.

2 URL Parser example output

Parsed Components

1
2
3
4
5
6
Protocol: https:
Host: example.com
Port: 8080
Path: /path/to/resource
Query: ?query=param&id=123
Hash: #section-1

3 Two jobs it does well

Routes that will not match

With the path, query and fragment shown separately, you can see where a stray slash or an encoded character ended up.

Pulling one piece out

Hover a row and click Copy to take only the host or only the pathname, without writing a regex that breaks on the next unusual URL.

How to use the URL Parser tool

  1. Paste a full URL including its scheme, such as https://example.com/path?x=1#top, into the editor. Upload File reads it from a .txt file, and Dummy Data loads a sample.
  2. The components list appears as you type: Protocol, Hostname, Port, Pathname, Search, Hash and Origin, plus Username and Password when the URL has credentials.
  3. Hover any row and click Copy to copy only that component.
  4. If the URL has a query string, a Query Parameters table lists each key and its decoded value, with one row per occurrence.
  5. A URL without a scheme shows "Invalid URL (ensure protocol like https:// is present)". Add https:// to the front and the parse succeeds.

How to parse a URL into its components in JavaScript, PHP and Python

JavaScript / Node.js

const url = new URL("https://user:pass@example.com:8080/path/page?q=hello%20world&ids=1&ids=2#top");

console.log(url.protocol); // https:
console.log(url.hostname); // example.com
console.log(url.port);     // 8080
console.log(url.pathname); // /path/page
console.log(url.search);   // ?q=hello%20world&ids=1&ids=2
console.log(url.hash);     // #top
console.log(url.origin);   // https://example.com:8080

// Query parameters are decoded for you
console.log(url.searchParams.get("q"));      // hello world
console.log(url.searchParams.getAll("ids")); // [ '1', '2' ]

// Relative URLs need a base
console.log(new URL("../img/logo.png", "https://example.com/a/b/").href);

url.port is an empty string when the port is the default for the scheme (80 for http, 443 for https).

PHP

<?php
$url = "https://user:pass@example.com:8080/path/page?q=hello%20world&ids[]=1&ids[]=2#top";

$parts = parse_url($url);
print_r($parts);
// [scheme] => https, [host] => example.com, [port] => 8080,
// [user] => user, [pass] => pass, [path] => /path/page,
// [query] => q=hello%20world&ids[]=1&ids[]=2, [fragment] => top

// A single component
echo parse_url($url, PHP_URL_HOST), PHP_EOL;

// Turn the query string into an array (brackets become nested arrays)
parse_str($parts["query"], $query);
print_r($query);

parse_url() does not validate or decode. Missing components are absent from the array, so use ?? defaults.

Python

from urllib.parse import urlparse, parse_qs

url = "https://user:pass@example.com:8080/path/page?q=hello%20world&ids=1&ids=2#top"
u = urlparse(url)

print(u.scheme)    # https
print(u.hostname)  # example.com
print(u.port)      # 8080
print(u.username)  # user
print(u.path)      # /path/page
print(u.query)     # q=hello%20world&ids=1&ids=2
print(u.fragment)  # top

# Every value is a list, because keys can repeat
print(parse_qs(u.query))
# {'q': ['hello world'], 'ids': ['1', '2']}

u.netloc holds the raw user:pass@host:port string, while hostname is lowercased and stripped of credentials.

Common errors and how to fix them

TypeError: Invalid URL / Failed to construct 'URL'
The string has no scheme, so example.com/page is not an absolute URL. Prepend https:// or pass a base URL as the second argument to new URL().
hostname is empty and the whole address sits in pathname
You parsed something like example.com:8080/path without a scheme, and some parsers read example.com as the scheme. Always include http:// or https://.
Query values are still percent-encoded
url.search, parse_url() and urlparse().query return the raw string. Use url.searchParams, parse_str() or parse_qs() to get decoded values.
The fragment (#section) never reaches my server
Browsers strip everything after # before sending a request, because the fragment is client-side only. If you need that value on the server, move it into a query parameter.
Port shows as empty even though I typed :443
The WHATWG URL parser drops a port that equals the scheme default. https://example.com:443 and https://example.com are the same origin.

Good to know

The parts always come in this order: scheme://username:password@host:port/path?query#fragment. Only scheme and host are required for an absolute URL. The origin, which is what the same-origin policy and CORS compare, is scheme plus host plus port and nothing more. Two URLs with different paths share an origin, but two with different ports do not. For example, a frontend on localhost:3000 calling an API on localhost:8000 is a cross-origin request.

This tool uses the WHATWG URL parser, the one browsers and Node.js ship. It normalizes as it parses: hosts are lowercased, default ports dropped, and dot segments like /a/../b resolved. PHP's parse_url() and Python's urlparse() do far less of that, so the same input can look slightly different depending on where you parsed it.

Specifications and references

This tool follows the specifications below. Read them when you need the exact normative wording, for example to settle an edge case between two implementations.

Frequently Asked Questions

Which parts of a URL are shown?

Protocol, hostname, port, pathname, search, hash and origin, plus username and password when the URL has credentials. A table below lists every query parameter.

Does it decode the query parameters?

Yes. The parameter table reads from url.searchParams, so names and values are percent-decoded and + becomes a space. The Search row shows the raw, still-encoded query string.

Can it parse relative URLs?

No. The tool calls new URL() without a base, so the input needs a scheme. A relative path such as /search?q=1 shows "Invalid URL (ensure protocol like https:// is present)". Add any origin in front, for example https://example.com/search?q=1, to inspect the path and query.

What about URLs with repeated parameters?

Each occurrence gets its own row in the parameter table, so ids=1&ids=2 shows two rows.

Which JavaScript API does this match?

The WHATWG URL and URLSearchParams interfaces built into browsers and Node.js. The results match what new URL() returns in your own code.

Related

The query string parser shows the parameters as a table and as JSON. For individual values, encode or decode them.

More URL Tools

Browse all url tools

Copied to clipboard!