We have always come across many links that are too long for our day to day usage and it is very difficult to remember them easily or to forward/share them whenever required. So this is where we require urls to be short and effective.
We will be building an short url generator by the help of NodeJS, mongoDBand expressJS.
- First step is to create the file architecture to create our project, so here I am using VS code as a code editor.
- Now open the terminal and initialize an npm file by using command
npm init
- Fill in the required details as your need
- Now create a file structure for managing the routes and views folder as shown in the image below.
- Now let's first install the dependencies that we require, open the terminal and hit:
npm i expressjs mongoose ejs shortid dotenv nodemon
Here the expressjs is used for setting the routes and mongoose is used for creating models for our DB, whereas ejs is for the frontend part for the viewing engine of the project and shortid is the main function that we are going to use to generate shortids/shorturl for the feed in url and at last the *dotenv * is an npm package for storing the credentials for accessing the DB.
- So after installing the packages/dependencies your package.json file should look like the image below and don't forget to change the scripts as shown below because we are going to require nodemon for speedy development of the app that automatically re-runs the server when any changes are made to the files.
{
"name": "url_shortner",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js"
},
"author": "Rohit",
"license": "ISC",
"dependencies": {
"dotenv": "^10.0.0",
"ejs": "^3.1.6",
"express": "^4.17.1",
"mongoose": "^6.0.7",
"shortid": "^2.2.16"
},
"devDependencies": {
"nodemon": "^2.0.12"
}
}
- First we are going to setup the dotenv file with the DB url we are going to connect to, in this project we will be connecting our app to our local mongoDB database, so update the .env file as shown below.
MONGO_DB_URL=mongodb://127.0.0.1:27017/urlshortnerappdb
- Now we are going to make a connection with the DB in the server.js file.
const express = require("express");
const mongoose = require("mongoose");
const app = express();
require("dotenv").config();
mongoose.connect(process.env.MONGO_DB_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
app.listen(process.env.PORT || 5000, () => {
console.log("SERVER RUNNING AT PORT 5000...");
});
The dotenv is included on the first line for requiring the dotenv file that has the DB url for connection, followed by requiring the express for creating an instance and then followed by requiring mongoose for making the connection.
We then define a port for listening to the server on port 5000 or a PORT that we can specify in the dotenv file.
- Now we are going to define the schema for the url DB by requiring mongoose and adding in the collections.
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,
},
},
{ timestamps: true }
);
module.exports = mongoose.model("ShortUrl", shortUrlSchema);
We have used the shortid package for generating random shortids for our url with the help of shortid.generate command and a clicks collection for storing the count of number of clicks that has been made on the shorturl link by people.
- Now add the view engine code part that is "ejs" in the index.ejs file.
<!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>URL shortner</title>
<style>
body {
background-color: powderblue;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
h1 {
color: blue;
}
button {
font-size: 17px;
color: white;
background-color: green;
border-radius: 15px;
width: 70px;
height: 50px;
}
form {
width: 50%;
display: flex;
}
input {
border-radius: 10px;
width: 100%;
height: 40px;
border: none;
margin: 10px;
}
table {
width: 70%;
padding-top: 20px;
}
table,
td,
th {
border-radius: 5px;
}
table,
thead,
tr {
font-size: 25px;
}
table,
tbody,
tr,
td {
font-size: 25px;
}
th {
text-align: left;
}
</style>
</head>
<body>
<h1>URL shortner</h1>
<form action="/shortUrls" method="POST">
<input type="url" name="fullUrl" id="fullUrl">
<button type="submit">Submit</button>
</form>
<table>
<thead>
<tr>
<th>Full URL</th>
<th>Short URL</th>
<th>Clicks</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>
</body>
</html>
and set the form action as "/shortUrls" because this is the endpoint which will help us to connect to the backend.
- Now we are going to add the routes in the server.js file.
const shortUrl = require("./models/shortUrl");
const ShortUrl = require("./models/shortUrl");
app.set("view engine", "ejs");
app.use(express.urlencoded({ extended: false }));
app.get("/", async (req, res) => {
const shortUrls = await ShortUrl.find();
res.render("index", { shortUrls: shortUrls });
});
app.post("/shortUrls", 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) return res.sendStatus(404);
shortUrl.clicks++;
shortUrl.save();
res.redirect(shortUrl.full);
});
We are going to set the view engine using app.set for viewing our ejs files and to pass json data from backend we set the app as app.use(express.urlencoded({ extended: false })).
The first route that is "/" will be the homepage for our application that will fetch all the previous url from the DB and render it using the ejs script.
The second route "/shortUrls" allows us to post/add urls to the DB
The third route "/:shortUrl" is what makes the connection between the original link and the short url link, so that it re-directs to the link that we want the short url for and it takes the id of the url stored in the DB as the params and then we are increasing the clicks count on the url.
- So the final code looks like:
const express = require("express");
const mongoose = require("mongoose");
const shortUrl = require("./models/shortUrl");
const app = express();
const ShortUrl = require("./models/shortUrl");
require("dotenv").config();
mongoose.connect(process.env.MONGO_DB_URL, {
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("index", { shortUrls: shortUrls });
});
app.post("/shortUrls", 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) return res.sendStatus(404);
shortUrl.clicks++;
shortUrl.save();
res.redirect(shortUrl.full);
});
app.listen(process.env.PORT || 5000, () => {
console.log("SERVER RUNNING AT PORT 5000...");
});
Now hit
npm start
in the terminal to start the app.
Enter the url for accessing the app as - localhost:5000 on your web-browser.
You will be able to see the following page:
So this is how you create a simple url shortner app using nodejs, expresjs and mongodb and can clip your urls into a small size.
Do hit the β₯ button if you liked the post and share it with your friends to let them know how to easily create an url shortner app.
FOLLOW @rohit23421 for more stuff on development and better practices for a developerπ.
Top comments (0)