npm init -y
npm i express
npm i mysql
npm i shortid
npm i ejs
index.js
const express = require("express"); const shortid = require("shortid"); const mysql = require("mysql"); const app = express(); app.set("view engine", "ejs"); app.use(express.static(__dirname + "/public")); app.use(express.urlencoded({ extended: false })); const db = mysql.createConnection({ host: "localhost", user: "root", password: "", database: "url_shortener" }); db.connect(err => { if(err) { console.log("Error connecting to DB"); return; } console.log("Connceted to DB"); }); function getLinks(req,res){ db.query("SELECT * FROM url ORDER BY ID DESC",(error,results) => { if(error){ res.render('home',{result:[]}) } else{ console.log(results) res.render('home',{results:results}) } }) } app.get("/", (req, res) => { getLinks(req,res) }); app.post("/shorturl", (req, res) => { const fullUrl = req.body.fullUrl; if (!fullUrl) { return res.sendStatus(404); } db.query('SELECT * FROM `url` WHERE `fullUrl` = ?', [fullUrl], (error, results) => { if (error) { console.log(error); return res.sendStatus(404); } if (results.length === 0) { const short = shortid.generate(); const url = { fullUrl: req.body.fullUrl, shortUrl: short, counts: 1 }; db.query('INSERT INTO `url` SET ?', url, (err, res) => { if (err) { console.log("Error creating table"); return; } }); getLinks(req,res) } else { const _short = results[0].shortUrl; const _counts = results[0].counts; db.query('UPDATE `url` SET `counts` = ? WHERE `shortUrl` = ?', [_counts + 1, _short], (err, res) => { if (err) { console.log("Error updating table"); return; } }); getLinks(req,res) } }); }); app.get("/:shortUrl", (req, res) => { db.query('SELECT * FROM `url` WHERE `shortUrl` = ?', [req.params.shortUrl], (error, results) => { if (error) { return res.sendStatus(404); } if (results.length === 0) { res.render("error"); } else { res.redirect(results[0].fullUrl); } }); }); app.listen(3000);
Now create a folder named public
and inside it make a css
folder and inside it make a home.css
file. After that, copy/paste the below code into it.
home.css
.container { width: 50%; margin: auto; text-align: center; display: flex; flex-direction: column; align-items: center; padding: 10px; } h2 { margin: 0; } p { max-width: 350px; } input[type="url"] { height: 28px; width: 250px; padding-left: 8px; border-radius: 4px; border: 1px solid #000; } input[type="submit"] { padding: 10px 20px; color: #fff; background-color: #349ded; border: none; border-radius: 4px; margin-left: 5px; } input[type="submit"]:hover { cursor: pointer; opacity: 0.85; } .span-link { padding: 10px 20px; border-radius: 4px; background-color: #349ded; color: #fff; } .result-container { background-color: #dddcdc; padding: 10px; min-width: 200px; display: flex; justify-content: space-around; } a { text-decoration: none; } .copy-span:hover { cursor: pointer; opacity: 0.75; }
And now make views
folder inside the root directory and inside it make two files namely home.ejs
and error.ejs
home.ejs
<!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 Shortener</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="/styles/home.css" /> </head> <body> <div class="container"> <h2>Bitly URL Shortener Clone</h2> <p>Convert long URL to shorter one with a single click. Its easy, simple and absolutely free!</p> <form action="/shortUrl" method="post"> <div class="form-group"> <input class="form-control" type="url" placeholder="Enter the URL" name="fullUrl" required /> </div> <div class="form-group"> <input class="form-control" type="submit" value="Convert" /> </div> </form> <%if(results){%> <table class="table table-bordered"> <thead> <tr> <th>FullUrl</th> <th>ShortUrl</th> <th>Count</th> </tr> <tbody> <%results.forEach(result=> {%> <tr> <td> <%=result.fullUrl%> </td> <td> <span><a id="short-url" href="<%= `/${result.shortUrl}` %>" target="_blank"><%= result.shortUrl %></a></span> </td> <td> <%=result.counts%> </td> </tr> <%})%> </tbody> </thead> </table> <%}%> </div> </body> </html>
error.ejs
<!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>Error Page</title> <link rel="stylesheet" type="text/css" href="/styles/home.css" /> </head> <body> <div class="container"> <h2>URL Shortener</h2> <p>The URL you entered does not exist!</p> <br /> <a href="/"><span class="span-link">Visit Home Page</span></a> </div> </body> </html>