This saved my bacon today and I quite like it so I hope that others might benefit from this little tip.
So you have two "URLs" and you want to know if they are "equal". I write those words, in the last sentence, in quotation marks because they might not be fully formed URLs and what you consider equal might depend on the current business logic.
In my case, I wanted http://www.peterbe.com/path/to?a=b
to be considered equal to/path/to#anchor
. Because, in this case the both share the exact same pathname (/path/to
). So how to do it:
function equalUrls(url1, url2) {
return (
new URL(url1, "http://example.com").pathname ===
new URL(url2, "http://example.com").pathname
);
}
If you're doing TypeScript, switch the arguments to (url1: string, url2: string)
.
That "http://example.com"
is deliberate and not a placeholder. It's because:
>> new URL("/just/a/path", "http://example.com").pathname
"/just/a/path"
>> new URL("https://www.peterbe.com/a/path", "http://example.com").pathname
"/a/path"
In other words, if you do it like that the first argument to the URL
constructor can be with or without a full absolute URL.
Discussion
Be careful with junk. For example new URL(null, 'http://example.com').pathname
becomes /null
. So you might want to extend the logic to use "falsyness" like this:
return (
+ url1 && url2 &&
new URL(url1, "http://example.com").pathname ===
new URL(url2, "http://example.com").pathname
);
Comments
I figured out few bothering situation: with / without last slash, url with query params ...
and my solution is using package called normalize-url: https://github.com/sindresorhus/normalize-url,
it has a related package called compare-urls: https://github.com/sindresorhus/compare-urls
Thank you!!
This is a very helpful solution. Thank you!