What a URL is made of
This URL parser splits an address into the parts RFC 3986 actually defines — scheme, userinfo, host, port, path, query and fragment — and tells you what each one decides. Paste an address, get a table. The point is not the split itself, which any regular expression can fake, but seeing the version the browser will really use, because that is the one your server and your CDN are going to see.
The parsing is done by the WHATWG URL engine already built into the browser, the same one behind
every fetch call. Writing another one would only produce a second opinion about something that
already has an authoritative answer on the machine you are sitting at.
Origin is the part that decides security
Three of the parts, taken together, form the origin, and almost every browser security rule is written in terms of it. Cross-origin request blocked, cookie not sent, storage empty, service worker out of scope — all of them are the same comparison of scheme, host and port.
What trips people up is how strict that comparison is. Moving a staging site from port 3000 to port 3001 changes the origin. Adding a subdomain changes it. Upgrading from http to https changes it, which is why a mixed-content page loses access to data written by its insecure twin. Local storage and IndexedDB follow origin exactly; cookies do not, because they predate the concept and are scoped by domain and path instead. That single inconsistency explains most of the confusion about why a login survives one hop and not another.
The query string has no standard
The path is defined by the specification. The query string, past the first question mark, is convention held together by habit. Nothing in the standard says pairs are separated by ampersands, nothing says a key may appear only once, and nothing says what a server should do when it appears twice. PHP wants brackets on the key, Rails wants brackets too but reads them differently, Express builds an array, and a plain servlet hands you the first value and silently drops the rest.
So this parser lists the pairs in the order they were sent, keeps duplicates, and shows both the decoded value and the raw text. If a key repeats, you get a warning rather than a guess, because guessing here is exactly the bug people arrive with.
Encoding is the second trap. A space arrives as either %20 or + depending on who built the link,
and both decode to a space. A literal plus must be written %2B or it disappears. An ampersand
inside a value has to be %26, or the pair simply ends early and you lose the rest.
Where the fragment goes
Nowhere. The fragment is the only part of a URL that never reaches the network. The browser removes it, keeps it in memory, requests the rest, and then uses the fragment to scroll or to feed a client-side router.
This has one genuinely useful consequence and one dangerous one. The useful one is that anything after a hash is free of server logs and referrer headers. The dangerous one is that "free of server logs" is not the same as private, since every script on the page can read it, which is why the OAuth implicit flow — which returned access tokens after a hash — is now discouraged.
Need to encode or decode a single component rather than take a whole address apart? The URL encoder and decoder does that one job. For turning a title into a path segment, the slug generator handles accents and length limits. And when the opaque string you are inspecting is a token rather than a link, the JWT decoder is the one you want.