Relative ↔ absolute URLs
Relative URL resolution has more cases than people remember: //host keeps the scheme, ?q=1 keeps the path, an empty reference means "this page without its fragment", and whether foo lands in the current directory depends on whether the base path ends in a slash. Resolve a whole list at once and see which rule fired for each.
How each reference resolved
How to use
- Set the Base URL — the address of the page the references appear on. It must be absolute.
- Paste the references, one per line. Mixed kinds are fine; each is classified separately.
- Read the How each reference resolved table. The note column names the rule, which is where the surprises show up.
- Switch Direction to go the other way: absolute URLs become the shortest reference that resolves back to them against your base.
The rules, with the traps marked
Path-relative (next.html, ../up.html) resolves against the base's directory, meaning everything after the last slash is discarded first. This is the trap: with a base of /docs/guide, the reference intro.html becomes /docs/intro.html — but with a base of /docs/guide/ it becomes /docs/guide/intro.html. One trailing slash, two different pages, and it is the reason a template that works on one route 404s on another.
Root-relative (/about) replaces the entire path, keeping only scheme and host. Reliable, which is why most build tools emit it.
Scheme-relative (//cdn.example.com/lib.js) keeps the base's scheme and replaces the host. Once recommended for assets that had to work over both HTTP and HTTPS; now an anti-pattern, since everything is HTTPS and it makes the URL ambiguous when copied out of context.
Query-only (?page=2) keeps the base's path and replaces the query — and drops the base's fragment. Fragment-only (#section) keeps everything and replaces only the fragment.
The empty reference resolves to the base URL with its fragment removed. That is why <a href=""> reloads the page rather than doing nothing, and why an empty action="" on a form posts to the current URL.
.. beyond the root is clamped, not an error: ../../../../x from /a/b gives /x. Do not rely on .. as a path-traversal defence — the parser normalises it away silently, which is exactly how traversal filters get bypassed when they check the raw string.
FAQ
Which specification does this follow?
The WHATWG URL Standard, because it uses the browser's own new URL(ref, base). That is what a browser, fetch, and most modern HTTP clients do. It differs from RFC 3986 in a few edge cases around backslashes and empty hosts, in the direction of matching real browser behaviour.
Why is one of my absolute URLs left absolute in relativize mode?
Because it is on a different origin, and no relative reference can reach a different host. If only the scheme differs, a scheme-relative //host/path form is produced instead.
Should I use relative or absolute URLs in my HTML?
Root-relative (/about) for internal links is the safe default — immune to the trailing-slash trap and portable between environments. Absolute URLs are required in email, RSS, sitemaps, canonical tags, hreflang and Open Graph tags, all of which are read outside the page's context.
Can it resolve every link in a page for me?
Yes — the HTML link audit takes pasted HTML plus a base URL and resolves every href and src to absolute form, with the anchor text alongside.