DEV Community

mehan
mehan

Posted on

Creating a url shortener in nodejs

Today we want to make a url shortener in nodejs. This project won't use a database to save the data, All the data will be saved in JSON file.

first of all, make sure you have installed nodejs. You can use nvm(Node version manager) to install it if you're using Linux.

Let's make the folder we want to code in there:

mkdir url-short
cd url-short
Enter fullscreen mode Exit fullscreen mode

We can make a public/ directory to put out HTML and CSS files in there. So:

mkdir public/
Enter fullscreen mode Exit fullscreen mode

And we will make a index.html in public/:

<!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">
    <title>Document</title>
    <link rel="stylesheet" href="index.css">
</head>
<body>
    <form action="/" method="post">
        <h1>Link shortener</h1>
        <input type="text" name="origUrl" id="">
        <button type="submit">shorten</button>
    </form>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

and index.css again in public/:

body{
    background-color: #00796B;
}
h1{
    color: #fff;
    font-size: 2em;
    font-weight: bold;
    text-align: center;
    margin: 0;
    font-family: Arial, Helvetica, sans-serif;
}
input{
    width: 70%;
    height: 2em;
    border: none;
    border-bottom: 1px solid #fff;
    background-color: #fff;
    color: #000;
    font-size: 1em;
    font-family: Arial, Helvetica, sans-serif;
    border-radius: 50px;
    margin-top:50px;
}
button{
    background-color: #1A237E;
    color: #fff;
    font-size: 1em;
    font-family: Arial, Helvetica, sans-serif;
    border: 0;
    border-radius: 50px;
    width: 70px;
    height: 40px;
}
Enter fullscreen mode Exit fullscreen mode

And now we will install npm package we need:

npm i express
Enter fullscreen mode Exit fullscreen mode

So We make a db.json in the root:

{links:[]}
Enter fullscreen mode Exit fullscreen mode

We will add urls to this later.
and index.js in the root:

const express = require("express")
const app = express()
const process = require("process")
const fs = require("fs")
const port = process.env.PORT || 4000


app.use(express.json())
app.use(express.urlencoded({ extended: true }))
// load html and css in public folder
app.use(express.static("public"))
app.get("/", (req, res) => { res.sendFile("index.html") })
Enter fullscreen mode Exit fullscreen mode

Ok So we know that index.html will send a post request to / containing original Url and we can get the data from db.json and chack if we have saved this url earlier:

app.post("/", (req, res) => {
    let newJson=JSON.parse(fs.readFileSync("./db.json"))
    const {origUrl} = req.body;
    // check if url isn't in json
    newJson.links.forEach(element => {
        if (element.url===origUrl) {
            res.send(`<h1>Your shorted link is http://localhost:${port}/${element.id}</h1>`)
        }
Enter fullscreen mode Exit fullscreen mode

But what if we haven't? We can make a id and store it json:

    // make the short id and put it in db.json
    let id = Math.random() * 10000000;
    id=Math.floor(id)
    // push to json
    newJson.links.push({
        id:id,
        url:origUrl
    })
    fs.writeFileSync("./db.json",JSON.stringify(newJson))
    res.send(`<h1>Your short url is: http://localhost:${port}/${id}</h1>`)
})
Enter fullscreen mode Exit fullscreen mode

Ok, So we saved the id with the original url. But if the user went to that id we must redirect the user to original url:

app.get("/:id",(req,res)=>{
    // redirect
    const id=req.params.id
    let newJson=JSON.parse(fs.readFileSync("./db.json"))
    let link=newJson.links.find(link=>link.id==id)
    if(link){
        res.redirect(link.url)
    }
    else{
        res.send("no link found")
    }
})
app.listen(port, () => console.log(`app listening on port ${port}!`))
Enter fullscreen mode Exit fullscreen mode

And so it works
demo :



Also I have uploaded the code in github: link

Top comments (0)