Basic Routing in Node.js
In our previous tutorial, we have learned how to render HTML files in Node.js. But in a typical web application, there will more than one page to load on accessing assigned paths. We need a routing system to handle such.
In this tutorial, we will construct a simple router in Node.js, without the use of any framework like Express.js.

To begin with, we will create three different HTML files and we will load them on accessing three different paths. We will load
-
index.html
on accessing the root path/
(this is the landing page) -
about.html
on accessing/about
-
services.html
on accessing/services
The three HTML files are as follows:
index.html
<!DOCTYPE html>
<html>
<head>
<title>Index Page</title>
</head>
<body>
<div>
Welcome to Node.js!
</div>
</body>
</html>
about.html
<!DOCTYPE html>
<html>
<head>
<title>About Page</title>
</head>
<body>
<div>
About Page
</div>
</body>
</html>
services.html
<!DOCTYPE html>
<html>
<head>
<title>Services Page</title>
</head>
<body>
<div>
Services Page
</div>
</body>
</html>
Router Setup
We set up our server.js
(or whatever name you gave your main file) as follows, making use of the switch-case
block for various routes.
const http = require('http');
const fs = require('fs');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
let htmlFile = '';
switch(req.url) {
case '/':
htmlFile = 'index.html';
break;
case '/about':
htmlFile = 'about.html';
break;
case '/services':
htmlFile = 'services.html';
break;
default:
break;
}
if(htmlFile)
render(res, htmlFile);
});
function render(res, htmlFile) {
fs.stat(`./${htmlFile}`, (err, stats) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html');
if(stats) {
fs.createReadStream(htmlFile).pipe(res);
} else {
res.statusCode = 404;
res.end('Sorry, page not found!');
}
});
}
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
We can do away with the switch-case
block and use an object instead to map the paths to respective files, which is much neater and less cumbersome. The routing system is assigned as a key-value pair to the routeMap
object.
const http = require('http');
const fs = require('fs');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html');
const routeMap = {
'': 'index.html',
'about': 'about.html',
'services': 'index.html'
}
render(res, routeMap[req.url.slice(1)]);
});
function render(res, htmlFile) {
fs.stat(`./${htmlFile}`, (err, stats) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html');
if(stats) {
fs.createReadStream(htmlFile).pipe(res);
} else {
res.statusCode = 404;
res.end('Sorry, page not found');
}
});
}
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});