UrlShortner using Nodejs and MongoDb | Node.js Project | Javascript
Tags: node, npm, mongodb, javascript
Published: 2020-07-03 05:47:55

Hello everyone, I'm **`Anuj Singh`**.


## Description about the project

In this post, I am going to show how you can make a URL shortener web application that shorts the provided full URL into short URL and also keeps a count on how many times that short URL has been clicked.

We will be using the following stack for this :

For FrontEnd - `HTML5 and CSS3 + Javascript`
For Backend  - `NodeJs`
For Database - `MongoDB`

# Let's start 

### Prerequisites :

1 : Install [NodeJs](https://nodejs.org/en/download/)

2 : Install [MongoDb](https://www.mongodb.com/download-center/community)

## Making The Folder Directory - 

*Note* - `Don't Make the node_modules, package.json and package-lock.jsn file now, it will be addressed afterward.`

In **.gitignore** file, write "node_modules". That's it.

![Folder Directory](https://i.imgur.com/SthBUzM.jpg)


### Files Used are - 

1 : **`index.js`**
   Starting Point to the Project, aka app.js
2 : **`shortUrl.js`**
   MongoDb schema for the project
3 : **`home.ejs`**
   The HTML code wrapped in *ejs* for dynamic HTML

Now open VSCode (or your own code editor) and open the terminal in the main folder after creating all those files.

**Step 1:** Run *`npm init`*, and fill the corresponding fields like :
(app.js) - index.js
(author) - your name
and yes yes enter enter in other. Even in *License* tap enter for default entry.

**`Update`**
So by now, you have *package.json* and *package-lock.json* file in your directory.

Now in *command terminal* type - 
**`npm install --save ejs express mongoose shortid nodemon`**

This will install the following npm package that will be used in creating and running of this project i.e 

*`ExpressJs`*
*`ShortId`*
*`Ejs`*
*`Mongoose`*
*`Nodemon`*

(**P.S** I'm not going in detail of these. You have *Google* use it)


###`Schema i.e shortUrl.js`

```
const mongoose = require('mongoose');
const shortId = require('shortid');


const shortUrlSchema = new mongoose.Schema({
    full:{
        type: String,
        required: true
    },
    short:{
        type: String,
        required: true,
        default: shortId.generate
    },
    clicks:{
        type:Number,
        required: true,
        default: 0
    }
});

module.exports = mongoose.model('ShortUrl',shortUrlSchema);
```
In this file, there are 3 sections.
`Full`: That stores actual URL
`Short`: That stores an unique short id generated by shortid library.
`Clicks`: That stores integer value of number of clicks.

###`home.ejs`

```
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
        integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <title>URL SHORTNER</title>
</head>
<body>
    <div class="container">
        <h1>Shrink URL</h1>
        <form action="/shortUrl" method="POST" class="my-4 form-inline">
            <label for="fullUrl" class="sr-only">Enter Full Url</label>
            <input type="text" required placeholder="Enter Here" name="fullUrl" id="fullUrl" class="form-control mr-2" style="width: 80%;">
            <button type="submit" class="btn btn-md btn-success">Shrink It !!</button>
        </form>

        <table class="table table-striped">
            <thead>
                <tr>
                    <th>Full Url</th>
                    <th>Shrinked Url</th>
                    <th>Clicked</th>
                </tr>
            </thead>
            <tbody>
                <% shortUrls.forEach(shortUrl => { %>
                    <tr>
                        <td><a href="<%=shortUrl.full%>"><%=shortUrl.full%></a></td>
                        <td><a href="<%=shortUrl.short%>"><%=shortUrl.short%></a></td>
                        <td><%=shortUrl.clicks%></td>
                    </tr>
                <% }) %>
            </tbody>
        </table>
    </div>
</body>
</html>

```

This is the frontend of the application, where the data is presented visually in table format. 

![Home.ejs](https://dev-to-uploads.s3.amazonaws.com/i/4fa9tlnhfk2gw9pkxunc.png)

###`Index.js`

```
const express = require('express');
const mongoose = require('mongoose');
const ShortUrl = require('./models/shortUrl');
const app = express();


mongoose.connect("<Enter your database connection url here>", {useNewUrlParser: true , 
useUnifiedTopology: true});

app.set('view engine' , 'ejs');
app.use(express.urlencoded({extended: false}));

app.get('/',async (req,res) => {
    const shortUrls = await ShortUrl.find()
    res.render('home',{shortUrls: shortUrls});
});

app.post('/shortUrl', async (req,res) => {
    await ShortUrl.create({full:req.body.fullUrl})
    res.redirect("/");
});

app.get('/:shortUrl', async (req,res) => {
    const shortUrl = await ShortUrl.findOne({short: req.params.shortUrl})
    if(shortUrl == null){
        res.sendStatus(404)
    }
    shortUrl.clicks++;
    shortUrl.save();
    res.redirect(shortUrl.full)
})

app.listen(process.env.PORT || 3000);

```

**NOTE** `Write your own DB connection url in mongoose.connect()`
Here on the submission of the data from the home.ejs page, the actual URL is stored in DB with a random unique shortid associated with it, and default clicks is 0. When someone clicks on the short URL, the shortUrl id is searched in the DB and coresponding actual id is returned back, also increasing the click by 1.


#THANK YOU !!!

##`Follow for more such stuff`
`Instagram : https://instagram.com/anujcodeop`
`Portfolio : https://anujportfolio.herokuapp.com`

{% github singhanuj620/urlShortner %}