Load/Serve a Simple HTML File in Node.js
We have built a simple Node.js HTTP web server in our previous tutorial. But that was just for plain texts. If you have to include some HTML tags along with the text, it will not render as you wish it.
For example, if the res.end('Hello, World\n')
statement from our previous code is changed to
res.end('<h1>Hello, World!</h1> \n');
the HTML tags will not be parsed and it will render as follows:
Fixing this requires just a small change by setting the Content-Type
of setHeader()
to text/html
.
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html');
res.end('<h1>Hello, World!</h1> \n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
That was some simple text enclosed between an <h1>
tag. But what if we have to serve an entire proper HTML 5 file? This is what we will be learning in this tutorial post.
Since we will be running our project locally, we set the hostname
variable to 127.0.0.1
. The port
variable is set to 3000
, so when the server is up, it will listen on port 3000. The fs
module allows you to read a file and serve it over HTTP (or HTTPS). The http module's createServer()
method returns an instance of the HTTP web server object. It also takes two arguments: an options
object, followed by a requestListener
function (the callback function here) which is called everytime the request event is triggered.
Serving an HTML File
We will load the below index.html
file, located in the same root directory as server.js
.
<!DOCTYPE html>
<html>
<head>
<title>Node.js</title>
</head>
<body>
<h1>Hello, Node.js</h1>
</body>
</html>
We use the fs.stat()
method to first check the existence of the file. Earlier, the fs.exists()
method could as well have been used, but it is already deprecated.
The content type of the header is set to text/html
inside the setHeader()
method belonging to the res
object of the callback function. The fs.createReadStream()
function opens up a readable stream. If a file path is passed to it, it starts streaming. The pipe()
method helps pipe out a readable stream from source to destination.
const http = require('http');
const fs = require('fs');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
if(req.url === '/') {
const htmlFile = 'index.html';
fs.stat(`./${htmlFile}`, (err, stats) => {
if(stats) {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html');
fs.createReadStream(htmlFile).pipe(res);
}
});
}
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
Now if you type
http://localhost:3000
on the browser's address bar, it will render as follows:
Now we will do a little alteration to load this index.html
file on accessing it via the path /index.html
. This is being done considering the impending need to load other files as well, such as about.html
, services.html
, privacy.html
, etc., when accessed via their respective paths /about.html
, /services.html
, /privacy.html
, etc.
const http = require('http');
const fs = require('fs');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
if(req.url === '/index.html') {
const htmlFile = req.url.slice(1);
fs.stat(`./${htmlFile}`, (err, stats) => {
if(stats) {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html');
fs.createReadStream(htmlFile).pipe(res);
}
});
}
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
So now, if you type
http://localhost:3000/index.html
on the browser's address bar, accessing the page /index.html
will also render as follows:
Now coming to the need to load other pages like about.html
, services.html
, privacy.html
, etc., proceeding the above way, we may have to write as many if
conditions (as such below) as the number of pages.
if(req.url === '/index.html')
Which means, for 100 pages, you may have to write 100 if
conditions. This actually is cumbersome. We can avoid this need for multiple if
checks using the endsWith()
method to check for .html
files as shown below. It will now load any existing HTML file in your project on accessing it by its name and extension.
const http = require('http');
const fs = require('fs');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
if(req.url.endsWith('.html')) {
const htmlFile = req.url.slice(1);
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}/`);
});