DEV Community

Cover image for Let's create a URL expander with Node.JS
Shuvo
Shuvo

Posted on

Let's create a URL expander with Node.JS

Yep we are creating a URL expander not a URL shortener

Node.JS URl expander preview
There are many tools like bitly, shorturl etc. through which we can convert our long and messy URL into a short and better looking URL. For example https://www.youtube.com/c/AngleBrace can become shorturl.at/asIW4.

But URL expander will do the opposite.

So we can get the original long URL from the short URL using it.

But why?

Well some bad guy can take this virus download link eg. https://www.badsite.com/virus.exe and shorten it to https://shorturl.at/wDPZ5. And now just by seeing the short URL you won't be able to tell that this link downloads a virus. So sometimes to prevent viruses and inappropriate websites we can use a URL Expander.

Lets start.

You can also see the video version on YouTube

So create a folder for the project. And open it up in the terminal. And then run npm init -y to create a new node js project. This will also create a package.json.
Initializing a new Node.JS project
After that we need to install some packages. We will need express and request. So install them by running npm i express request
We will also install nodemon as our dev dependency. So we won't have to rerun the JavaScript file each time we make a change. So install it by running npm i nodemon -D
Now in the package.json we will delete the test script and create a start script.

{
  "name": "url_expander",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "nodemon index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1",
    "request": "^2.88.2"
  },
  "devDependencies": {
    "nodemon": "^2.0.15"
  }
}
Enter fullscreen mode Exit fullscreen mode

Okay now lets create a index.js file and setup a basic NodeJS and Express project

const express = require('express')
const app = express()

app.use(express.static('public'))

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html')
})

app.listen(3000, () => {
    console.log('Server is running on port 3000')
})
Enter fullscreen mode Exit fullscreen mode

So now we can create a public folder. Inside that we will create our HTML, CSS and JS file. So our folder structure will look something like this
NodeJS project folder structure
Okay now in out HTML let's write some markup. We will have 3 main elements

  1. A input where we can enter the short URL
  2. Button that will send the request to expand URL
  3. A element were we will show our expanded URL
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title>Node JS URL Expander</title>
</head>
<body>
    <div class="container">
        <div class="input-box">
            <input type="text" id="input" placeholder="Enter Short URL">
            <button id="expand-btn">expand</button>
        </div>
        <a href="" id="result"></a><!-- Expanded URl will be shown here -->
    </div>

    <script src="main.js"></script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Now lets style it in our style.css

*{
    margin: 0;
    padding: 0;
}
html, body{
    height: 100%;
}
body{
    background-color: rgb(239, 131, 84);
    display: flex;
    justify-content: center;
    align-items: center;
}

.container{
    width: 320px;
    padding: 3em;
    background-color: rgba(255, 255, 255, 0.3);
}
.input-box{
    height: 35px;
    display: flex;
}
input{
    flex-grow: 1;
}
button{
    background-color: rgb(233, 95, 35);
    color: white;
    text-transform: uppercase;
}
input, button{
    padding: 0 1em;
    display: block;
    border: none;
    outline: none;
}

#result{
    color: white;
    word-break: break-all;
    font-size: 1.2em;
    text-align: center;
    display: block;
    margin-top: 1em;
}
Enter fullscreen mode Exit fullscreen mode

So now if we start our server by running npm start and go to localhost:3000 we should see this page
Nodejs project on localhost
Great Now in our main.js lets make it so when we click on the button it sends a request to /expand and displays the response.

const input = document.querySelector('#input')
const expandBtn = document.querySelector('#expand-btn')
const result = document.querySelector('#result')

expandBtn.addEventListener('click', () => {
    // Initally set the result to loading
    result.innerText = 'Loading ...'
    fetch(`/expand`)
        .then(res => res.text())
        .then(text => {
            // Display the result send from the server
            result.innerText = text
        })
        .catch(err => {
            console.log(err)
            result.innerText = 'Error'
        })
})
Enter fullscreen mode Exit fullscreen mode

Now in our index.js lets create the /expand route.

const express = require('express')
const app = express()

app.use(express.static('public'))

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html')
})

app.get('/expand', (req, res) => {
    res.send("hello")
})

app.listen(3000, () => {
    console.log('Server is running on port 3000')
})
Enter fullscreen mode Exit fullscreen mode

So now if we click on the button it should display hello
NodeJS send fetch request from html
Okay now in out main.js when sending request to /expand lets also send our inputs value as a query parameter.

const input = document.querySelector('#input')
const expandBtn = document.querySelector('#expand-btn')
const result = document.querySelector('#result')

expandBtn.addEventListener('click', () => {
    result.innerText = 'Loading ...'
    // passing the input value to the server as shortUrl query string
    fetch(`/expand?shortUrl=${input.value}`)
        .then(res => res.text())
        .then(text => {
            result.innerText = text
        })
        .catch(err => {
            console.log(err)
            result.innerText = 'Error'
        })
})
Enter fullscreen mode Exit fullscreen mode

So now we can get the input value in our index.js

app.get('/expand', (req, res) => {
    let shortUrl = req.query.shortUrl
    res.send("hello")
})
Enter fullscreen mode Exit fullscreen mode

And now finally we can use the request package we installed earlier to get the original URL of our short URL

const express = require('express')
const request = require('request')
const app = express()

app.use(express.static('public'))

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html')
})

app.get('/expand', (req, res) => {
    let shortUrl = req.query.shortUrl
    // If the shortUrl doesn't start with http, add add https:// in front of it
    // So eg. example.com becomes https://example.com
    if(!shortUrl.startsWith('http')) shortUrl = 'https://' + shortUrl
    request({
        url: shortUrl,
        method: "HEAD",
        followAllRedirects: true
    },
    (err, response, body) => {
        if (err) {
            console.log(err)
            res.send("Error")
        } else {
            // Sending back the full url
            res.send(response.request.href)
        }
    })
})

app.listen(3000, () => {
    console.log('Server is running on port 3000')
})
Enter fullscreen mode Exit fullscreen mode

And now our project is complete. So enter a short URL like shorturl.at/aoqyO and click on expand and it should display the full URL
Working Node JS URL expander

You can the finished codes here

Make sure you checkout my other articles and YouTube Channel

0shuvo0 image

Was it helpful? Support me on Patreon

Patreon Logo

Discussion (9)

Collapse
joeattardi profile image
Joe Attardi

Couple of quick observations:

  • The request module has been deprecated for some time, new projects should not be using it, this sets a bad example.

  • I think your articles like this would be better if you would give an overview of the approach to the problem rather than diving right in to the code. Especially for newer developers who may not be able to follow all the logic.

Collapse
0shuvo0 profile image
Shuvo Author

Thanks
But about the 1st point
Deprecated just means it no longer maintained, its okay to still use it

Collapse
Sloan, the sloth mascot
Comment deleted
thatsbrandon profile image
Brandon J

I wrote a small networking class for my NodeJS project the other week. I used https.request, worked like a charm & wasn't that difficult to use!

Collapse
nmhillusion profile image
nmhillusion

Nice. But how if that short link needs verification (example, recaptcha) to go to the original link?

Collapse
0shuvo0 profile image
Shuvo Author

yes then it would have to be may more complex unless captha shows onpage after landing on the destination

Collapse
nmhillusion profile image
nmhillusion

yeap

Collapse
amruthpillai profile image
Amruth Pillai

Really smart solution to finding the real link, nice work on the video and post! 🙌

Collapse
0shuvo0 profile image
Shuvo Author

Many many thanks 💓