URL Parser / Inspector Guide
What is a URL parser?
A URL parser takes a URL string and breaks it into the parts your code actually works with: scheme, authority, hostname, port, path, query string, and fragment. Instead of treating https://user:pass@example.com:8443/app?a=1#top as one opaque blob, it exposes the structure so you can inspect each component directly.
That sounds basic until you hit real input. URLs can contain credentials, IPv6 literals, percent-encoded characters, repeated query parameters, and relative references that only make sense with a base URL. A good URL inspector does more than split on / and ?; it follows the platform parser and shows where normalization happens.
This Toolzy.dev page is built for local inspection in the browser. If you need to parse URL online without pasting internal links, auth callbacks, or signed URLs into a server-backed service, keeping the inspection client-side is the safer option.
How to use this tool
- Paste a full URL or URL-like input into the field.
- Review the parsed fields such as protocol, host, port, pathname, search, and hash.
- Expand the query breakdown if you need to inspect URL parts inside
?key=valuepairs. - Compare the raw input with the normalized output before copying values into code or docs.
If the input is relative, interpret the result carefully. Relative references are valid, but they need a base URL for full resolution.
Common use cases
- Debug OAuth or SSO callback URLs with long
redirect_uri,state, orscopevalues - Check whether a frontend route bug lives in the path, query string, or fragment
- Inspect API endpoint strings copied from logs before using them in tests
- Verify whether a URL contains embedded credentials or a non-default port
- Break down analytics links full of
utm_*parameters and encoded landing page paths - Compare browser normalization with the exact literal string generated by your app
URL structure: scheme, authority, path, query, hash
Most developer discussions compress "the URL" into one term, but the structure matters:
protocolor scheme:https:- authority:
//user:pass@example.com:8443 - path:
/docs/page - query:
?tab=api&lang=en - fragment or hash:
#install
Given:
https://user:pass@example.com:8443/docs/page?tab=api&lang=en#install
the parser can separate data that affects transport from data that only affects client behavior. The fragment is the easiest example. It is part of the URL in the browser, but it is not sent to the server in a normal HTTP request.
Authority is where several useful sub-parts live:
- username:
user - password:
pass - hostname:
example.com - port:
8443
When you inspect URL parts this way, debugging becomes much faster. You stop asking "why is this link broken?" and start asking "is the port wrong, is the path malformed, or is the query value encoded incorrectly?"
Absolute vs relative URLs
One of the most common mistakes in URL breakdown tools is pretending every input should parse as an absolute URL. That is not how the platform works.
Absolute URLs include a scheme and enough information to stand alone:
https://example.com/docsmailto:dev@example.comfile:///tmp/report.txt
Relative references depend on a base:
/docs../images/logo.png?page=2#section-3
In the browser, relative parsing is explicit:
new URL("/docs", "https://example.com/app/");
// https://example.com/docs
Without a base URL, new URL("/docs") throws. That is the honest behavior. A relative input is not invalid in general; it is unresolved.
Browser normalization and serialization behavior
Parsing a URL is not the same thing as preserving the original string byte for byte. Browser URL implementations normalize aggressively in ways that are usually helpful:
- Hostnames are lowercased
- Dot segments like
/a/../bare resolved - Default ports may disappear
- Certain characters are percent-encoded during serialization
Example:
const url = new URL("HTTP://EXAMPLE.COM:80/a/../b?q=hello world#Top");
url.href;
// "http://example.com/b?q=hello%20world#Top"
That normalized string is often what your browser, router, or fetch call will use. If you are validating signatures or comparing exact literals, remember that the parser's serialized output may not match the original text even when the meaning is the same.
Protocol, hostname, and default ports
Default ports are tied to the scheme. http: defaults to 80, https: defaults to 443, ws: defaults to 80, and wss: defaults to 443. When those default ports are explicitly present, browser serialization may omit them.
That means these two URLs are usually treated as equivalent by the parser:
https://example.com/pathhttps://example.com:443/path
But non-default ports are significant:
https://example.com:8443/path
The same hostname with a different port is a different origin. That matters for cookies, CORS, local development, reverse proxies, and auth callbacks.
Credentials in URLs
Credentials can appear before the host:
https://user:pass@example.com/private
Parsers expose this as username and password, but it is worth being blunt: embedding credentials in URLs is usually a bad idea. They can leak through logs, browser history, copy-paste, and monitoring tools.
This is one reason local browser-based inspection is useful. If you need to inspect a URL that already contains credentials, API tokens, or signed query parameters, you can review it without shipping the string to a remote service.
Path handling, encoding, and special characters
The path is not just the string after the host. It has its own encoding rules, separator semantics, and normalization behavior.
For example, these are not equivalent in meaning:
/files/a/b/files/a%2Fb
In the first case, / separates path segments. In the second, %2F is encoded data that may represent a literal slash inside one segment, depending on how your app interprets it.
Spaces and Unicode also matter. A browser may serialize:
/docs/hello worldas/docs/hello%20world/cafe%CC%81or/caf%C3%A9style Unicode paths as percent-encoded UTF-8 when sent over the wire
If a route looks correct visually but still fails, inspect the encoded path instead of the rendered text.
Query parameter parsing and repeated keys
The query string is where many "simple URL" assumptions fall apart. Query parameters are text pairs separated by &, but repeated keys and encoding rules make inspection important.
Example:
https://example.com/search?q=url+parser&tag=js&tag=web&redirect=%2Fdocs%3Ftab%3Dapi
A useful URL inspector should let you see at least this breakdown:
q->url parsertag->js,webredirect->/docs?tab=api
Repeated keys are valid. Whether your app reads one value or all values depends on the code you use. In browser JavaScript:
const params = new URLSearchParams("tag=js&tag=web");
params.get("tag");
// "js"
params.getAll("tag");
// ["js", "web"]
That difference matters when you parse filters, multi-select state, or callback data.
Browser decoding is forgiving too: malformed percent escapes are still surfaced the way URLSearchParams does, rather than causing a hard decode error.
Hash fragments and client-only state
Fragments are useful for anchor links, SPA state, and in-page navigation:
#intro#tab=settings
They are visible in the browser and accessible to client-side code, but they are not part of the HTTP request target. If your backend logs never show the value after #, that is expected.
This distinction is especially important when debugging frontend routers or analytics. A fragment bug and a query-string bug can look similar in the address bar while behaving very differently in production.
URL normalization vs URL comparison
If you need a URL breakdown for debugging, normalization is helpful. If you need exact string equality, normalization can surprise you.
These may resolve to the same effective address:
https://EXAMPLE.com:443/docshttps://example.com/docs
These may not:
https://example.com/docshttps://example.com/docs/
Whether trailing slash differences matter depends on the server, router, CDN, or framework. A URL parser can tell you how the browser sees the components, but application-level equality rules still belong to your stack.
Troubleshooting
Why does the tool reject /api/users as a full URL? — /api/users is a relative reference, not a self-contained absolute URL. It needs a base like https://example.com for full resolution.
Why did :443 or :80 disappear from the parsed result? — The parser likely normalized a default port away because it is implied by the scheme.
Why did my hostname change from EXAMPLE.COM to example.com? — Hostnames are case-insensitive, so browser URL parsers usually lowercase them during normalization.
Why is #section-2 missing from my server logs? — Fragments are client-side only and are not sent in normal HTTP requests.
Why does tag=js&tag=web only show one value in my app? — Your app may be using single-value query access like URLSearchParams.get() instead of preserving duplicates with getAll().
Why does %2F stay encoded in some places? — Encoded slash can carry different meaning from a path separator. Some tools preserve encoded form in the raw URL while decoding values only in specific inspected fields.
Why doesn't the normalized output exactly match what I pasted? — Browser parsers serialize URLs into a canonical form, which can lowercase the host, remove default ports, resolve dot segments, and encode spaces.