May 17, 2022

How to validate a URL with Node JS

How to validate a URL with Node JS

Recently I needed to validate http links with Node. I thought this should be easy, and it is. Luckily for us, Node has a built in URL module that can help us to this.

This is the snippet(not the final one):

const URL = require('url').URL

// 1
function validateUrl(urlString) {
  // 2
  return new URL(urlString)
}

// 3
validateUrl('https://google.com')
validateUrl('https:google.com')
validateUrl('sometext.com')
validateUrl('sometext')

So, what are we doing here?

  1. Create a simple function that will create and return an instance of URL.
  2. This is where we create an instance of URL(well, hopefully we create a new instance, more on that later).
  3. Call the validateUrl function to see which of the urls are valid.

I am not going to add the output here, you can copy this code and run it for yourself, but, this code fails on the third url, sometext.com.

Failing code is not great, especially for this use case. So, how can we improve it?

const URL = require('url').URL

function validateUrl(urlString) {
  try {
    new URL(urlString)
    return true
  } catch {
    return false
  }
} 

console.log(validateUrl('https://google.com'))
console.log(validateUrl('https:google.com'))
console.log(validateUrl('sometext.com'))
console.log(validateUrl('sometext'))

This code is similar in the sense that we are still creating a new URL instance to try and see if our url is valid.

The big change here is that this, validateUrl, function returns a boolean value, for ease of use in a true/false situation, we are also wrapping new URL() in a try catch so that we can return a value based on whether new URL fails or not.

This way we can handle the issue in this function and we don't need a try catch in other places of our code. In some situation this might not be beneficial and you might need to tweak this code to suit your situation a bit better, for eg, if you want custom errors and you want those errors to be returned for some reason etc.

Conclusion

To be honest, once I found this solution, I didn't try to see if there is a cleaner way. I don't really like new URL(urlString) just hanging there in mid air. For my current purposes this works as I need it to.

I will update this post in the future if I find a nicer way to do this.