Introduction
In this article, we are going to a build simple app to serve static files like HTML files, CSS files, and images using Node.js and Express.
Configuring the Project and Installing Express
To get started, let's create a new Node.js project by running the init
command in a new folder:
$ npm init
Fill the requested information to your requirements or just set the default values by leaving each line blank.
Now we can install the Express framework by running:
$ npm install --save express
We are all set, let's start coding!
Serving Files with Express
There are two ways to serve static files using Express:
- Serving a single file by configuring a path to the resource
- Setting a public directory in which all files are accessible
We'll go over each of these methods in the next two sections.
Serving a Single File
Consider a scenario when we want to create a simple landing page that consists of 3 HTML documents (home.html
, contact.html
, and about.html
), and we want to serve these files to the user.
Let's assume that the user visits the root path (http://localhost:3000
). In that case, we want to serve the home.html
file. Similarly, if the user visits the /contacts
or /about
paths, we want to serve the contact.html
and about.html
files, respectively.
To implement this, let's create a landing-page.js
file and import the Express library:
const express = require('express');
Then, we'll create the Express app:
const app = express();
Then let's define the port on which our server will be running, which we'll use later when we actually run the server:
const port = 3000;
Since we are sending a single file, we won't include links to any CSS or script files within those HTML files unless they are hosted in a different location, like a CDN, for example.
We'll handle serving these files together in the next section, so for now, let's stick with three very simple, bare-bone HTML files:
home.html:
<body>
<h1>Home</h1>
</body>
contact.html:
<body>
<h1>Contact</h1>
</body>
about.html:
<body>
<h1>About Us</h1>
</body>
Now let's go back and edit our landing-page.js
file to send files corresponding to the paths the user visits, such as sending the home.html
file when the user visits the root path.
We can use the res.sendFile()
method to serve a file within a response:
app.get('/', (req, res) => {
res.sendFile('./landing-page/home.html', { root: __dirname });
});
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
For security reasons, it's best to use a static path for res.sendFile()
, as shown above. If you're ever taking user input that affects the file path, be very careful to prevent the user from being able to manipulate the file path and thus allowing them to retrieve private files.
In our case, we're setting the root for where the relative path is from by passing the root
parameter to the method. Note that, we have passed __dirname
, which is a Node.js global variable to the path of currently running file.
We can use the same method to serve our other files, contact.html
and about.html
, as well:
app.get('/about', (req, res) => {
res.sendFile('./landing-page/about.html', { root: __dirname });
});
app.get('/contact', (req, res) => {
res.sendFile('./landing-page/contact.html', { root: __dirname });
});
Now that our application is ready to go, let's start the server and listen to the port we set earlier:
app.listen(port, () => console.log(`listening on port ${port}!`));
And run our app by executing:
$ node landing-page.js
Open your browser and visit any of the mapped paths and you should be greeted with the HTML file(s):
Setting up a Public Directory
The second method of serving static files is to set up a public directory. Unlike sending a file through the HTTP response, where only a single file can be served, all files inside our specified folder will be available for users.
Let's create another file, called server.js
, and set the folder with our three HTML documents to be a public directory:
const express = require('express');
const app = express();
const port = 3000;
// Setting up the public directory
app.use(express.static('landing-page'));
app.listen(port, () => console.log(`listening on port ${port}!`));
Making a directory public is as easy as using the app.use()
and express.static()
methods.
Let's run our app again and verify that it's working:
$ node server.js
Open your browser and visit any of the mapped paths and you should be greeted with the HTML files, just like last time. Keep in mind that this time, the root path is not mapped to the home.html
file, but rather the http://localhost:3000/home.html
:
Also, you can set a prefix to the path to access your public directory by passing the prefix as the first parameter:
app.use('/public', express.static('landing-page'));
Now, the files are situated on another path. For an example, home.html
is now located at http://localhost:3000/public/home.html
.
Unlike the first method where you'd hit /about
and about.html
would be served, note that you have to use the full file name in order to retrieve the file here - /about.html
, for an example.
This allows us to host other files such as CSS, JavaScript files, and images as well.
For example, if there is a cat image on your public folder called cat.png
, the server will be serving it on http://localhost:3000/public/cat.png
depending on your configuration and you can easily call it via an HTML page and display it.
If you are planning to host a landing page like this, most probably it could be a combination of both methods that we discussed above. You can use a response to send a single HTML file and a public directory to host other static assets such as CSS files, JS scripts, and images.
Conclusion
The source code of this project is available on GitHub as usual. Use this to compare your code if you ever got stuck along the tutorial.
Happy Coding!