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

john

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

Peter Bengtsson

Thank you!!

Aaron

This is a very helpful solution. Thank you!

Your email will never ever be published.

Related posts