TidyURLs
Go to Tools
BLOG
The TidyURLsJournal

Practical guides, tutorials, and insights about URLs, SEO, web development, and online marketing. Learn, troubleshoot, and get the most of the web.

Back to the Journal
TidyURLs Journal

How to Parse a URL: A Field-by-Field Guide

Practical insights, clear explanations, and useful ideas for understanding the web.

October 28, 20267 min read5 topics
How to Parse a URL: A Field-by-Field Guide
Explore the details
#URL parsing#JavaScript#Web development#HTTP#Debugging
October 28, 20267 min read

A complex URL can look like one long string, but each part has a different job. Knowing how to parse a URL helps you debug links, understand requests, and distinguish what the browser parses from what your application does with the result.

This guide breaks down a realistic URL, shows how to inspect it with JavaScript, and covers repeated query keys, encoded characters, credentials, and ports.

Key Takeaways

  • A URL has distinct components: scheme, hostname, optional port, path, query, and fragment. Some URLs also include user information.
  • Use a standards-based parser, such as JavaScript’s URL class, rather than splitting a URL on punctuation.
  • Query strings and paths are structured data, but their meaning is defined by the application that handles them.
  • Query keys can repeat, and percent-encoded characters may be decoded differently depending on the component and the API you use.
  • A fragment is for client-side navigation or processing; it is not sent as part of the HTTP request.

A URL, Split into Its Parts

Consider this example. The credentials are fictional and included only to illustrate URL syntax; do not put real secrets in URLs.

https://demo:example@example.com:8443/products/item%2F42?tag=red&tag=blue&next=%2Fsearch%3Fq%3Dtea#reviews

Read it from left to right:

ComponentExample valueWhat it represents
SchemehttpsThe URL’s scheme. In JavaScript’s URL object, this is exposed as protocol and includes the colon: https:.
UsernamedemoOptional user information before the @.
PasswordexampleOptional user information after the username and colon.
Hostnameexample.comThe host name.
Port8443An explicit port following the hostname.
Path/products/item%2F42The resource path.
Query?tag=red&tag=blue&next=%2Fsearch%3Fq%3DteaParameters following ?. Keys can repeat.
Fragment#reviewsA client-side reference following #.

The @ marks the end of user information and the start of the host. The colon after the hostname introduces the port. A URL’s host includes the port when one is present; its hostname does not.

A port is optional. For HTTPS, 443 is the default port, so a standards-based parser can normalize https://example.com:443/ to a URL whose serialized form omits that port. The example’s 8443 is non-default, so it remains explicit.

Parse a URL with JavaScript

In browsers and modern JavaScript runtimes, the built-in URL class exposes URL components as properties. This example uses an absolute URL, so it does not need a base URL.

const input =
  "https://demo:example@example.com:8443/products/item%2F42?tag=red&tag=blue&next=%2Fsearch%3Fq%3Dtea#reviews";

const url = new URL(input);

console.log(url.protocol);  // "https:"
console.log(url.username);  // "demo"
console.log(url.password);  // "example"
console.log(url.hostname);  // "example.com"
console.log(url.port);      // "8443"
console.log(url.host);      // "example.com:8443"
console.log(url.pathname);  // "/products/item%2F42"
console.log(url.search);    // "?tag=red&tag=blue&next=%2Fsearch%3Fq%3Dtea"
console.log(url.hash);      // "#reviews"

const params = url.searchParams;
console.log(params.getAll("tag")); // ["red", "blue"]
console.log(params.get("next"));   // "/search?q=tea"

URLSearchParams is useful for query data: getAll() returns every value for a repeated key, while get() returns the first matching value. If an input might be invalid, constructing a URL can throw a TypeError; catch that error when handling untrusted input. For a relative reference such as /products, supply a base: new URL("/products", "https://example.com").

The URL API follows the WHATWG URL parsing and serialization model. That model is more involved than splitting a string at ?, #, or :: those characters can have different significance depending on where they appear, and parsing can normalize some representations.

Repeated Keys and Encoded Characters

Repeated query keys are valid. In the example, tag occurs twice. Do not assume that a query string is a simple object with one value per key. Use getAll() when all values matter, or choose an application-specific policy if your server or framework expects a single value.

Percent-encoding represents characters using % followed by hexadecimal digits. In the example, %2F is an encoded slash in the path, and %3F is an encoded question mark in the next query value. The URL parser leaves the path’s encoded slash visible in pathname, while URLSearchParams decodes the query value when reading it. That decoded value, /search?q=tea, is still just a string; it is not automatically parsed as a nested URL.

Be careful when decoding or re-encoding values. Characters such as /, ?, and & can act as delimiters in some URL components. Decoding an encoded delimiter before routing or validating a path may change how later code interprets it. Follow the expectations of the specific server, framework, and application rather than assuming every layer decodes identically.

In query strings handled by URLSearchParams, + is interpreted as a space when reading form-style query data. A literal plus sign is commonly represented as %2B. If exact byte-level representation matters, retain or inspect the original input rather than relying only on decoded parameter values.

Credentials, Ports, and Request Boundaries

User information appears before the @, as in demo:example@. It is part of the URL syntax, but it is rarely appropriate to share or log URLs containing credentials. URLs may be copied, stored, or included in logs and analytics. Avoid putting passwords, API keys, or other secrets there.

The port identifies a service endpoint on the host. It is not part of the hostname: in the example, hostname is example.com, while host is example.com:8443. When comparing URLs or enforcing an allowlist, account for the scheme and port as well as the hostname; checking only a hostname may not describe the destination you intend to allow.

A fragment begins at #. It can help a browser navigate to a section or support client-side application state, but it is not included in the HTTP request sent to the server. The query, by contrast, is part of the request target in ordinary HTTP requests.

Syntax Is Not Application Meaning

A parser identifies structure; it does not decide what the structure means to your application. For example, the URL parser can identify two tag values, but your application decides whether those values are filters, labels, or invalid input. Likewise, a path such as /products/item%2F42 has a parsed pathname, but the server’s routing and decoding rules determine which resource it refers to.

Parsing is also not a security policy. If your application accepts URLs for redirects, server-side fetching, or other sensitive operations, validate them against the requirements of that operation. A successful parse does not establish that a destination is trusted or safe.

Common Mistakes

  • Splitting on punctuation. A colon, slash, question mark, or @ can mean different things in different URL components. Use a URL parser.
  • Assuming query keys are unique. Repeated keys are valid; inspect all values when the application may send them.
  • Treating encoded and decoded text as interchangeable. Decoding reserved characters can affect how later code interprets a path or query.
  • Using host when you need only the hostname, or vice versa. host includes a non-default port; hostname does not.
  • Expecting the server to receive the fragment. The fragment is not sent in the HTTP request.
  • Assuming a parsed URL is safe or meaningful. Parsing describes structure, not application intent or authorization.

Best Practices

  1. Parse URLs with the platform’s URL API instead of manually splitting strings.
  2. Handle invalid input and use a base URL when parsing relative references.
  3. Use URLSearchParams for query values, and explicitly decide how repeated keys should be handled.
  4. Preserve the distinction between encoded input and decoded values where routing or validation depends on it.
  5. Avoid credentials and other secrets in URLs.
  6. Apply application-specific validation after parsing; do not treat parsing alone as a security check.

Conclusion

To debug a complex URL, identify its components with a standards-based parser, then check how the relevant application interprets them. Pay particular attention to repeated query keys, encoded delimiters, explicit ports, and the fact that fragments stay on the client side.

References

I could not retrieve external documentation while preparing this guide, so I cannot confirm the current text of the relevant references here. For authoritative details, consult the WHATWG URL Standard and the MDN URL reference.