I am Hack Sparrow
Captain of the Internets.

How to serve static HTML files in Express.js

Express.js comes with a badass HTML pre-processor, Jade, but sometimes you may just want to use the good old HTML files for whatever reason. Is there a way to accomplish this? Oh yes, there is!

The short and quick answer to this requirement is - dump the files in the public directory!

There is a slightly more elaborate but cleaner method, which will help you from cluttering up your public directory with the HTML files - use the static middleware.

Create a directory to keep your HTML files.

$ mkdir html
$ touch ./html/contact.html
$ touch ./html/hello.html

Add some relevant HTML code in the files.

contact.html

<html>
    <b>Keep in touch with mama kin</b>
</html>

hello.html

<html>
    <i>You say goodbye, and I say hello</i>
</html>

Now, add this line in app.js.

// we are specifying the html directory as another public directory
app.use(express.static(path.join(__dirname, 'html')));

Start the app, the two files will be available at http://localhost:3000/contact.html and http://localhost:3000/hello.html.

Now, is there a way to serve static HTML files but still have the flexibility of routes and the access to the req and res objects? Yes there is - use the req.sendfile() method to send the HTML file.

Note: When you use req.sendfile(), it is significant to have the opening and closing HTML tags in the HTML files, otherwise some browser-based debuggers just won't show the Content-Type as HTML at all and you will be left trying to debug why Express is not sending the Content-Type header.

Add the following to app.js.

// a convenient variable to refer to the HTML directory
var html_dir = './html/';

// routes to serve the static HTML files
app.get('/contact', function(req, res) {
    res.sendfile(html_dir + 'contact.html');
});
// Note: route names need not match the file name
app.get('/hello', function(req, res) {
    res.sendfile(html_dir + 'hello.html');
});

You can add any additional HTTP headers that you might like to add to the response using the res.set() method, but the Content-Type header will be added by Express based on the file extension.

Start the app and load up http://localhost:3000/contact and http://localhost:3000/hello to see the HTML files in the browser.

Although this method of serving static HTML or any other files from Express is fine for testing, and on low traffic websites. If you plan on something bigger, use a front-facing proxy like Nginx to serve the files instead, that way your Express app can focus on the dynamic requests and save some processing power for activities more relevant to it.

4 Responses to “How to serve static HTML files in Express.js”

  1. Matthew says:

    Why not use express.static? http://expressjs.com/api.html#app.use. Only disadvantage I see is that it might be difficult to remove the file extension from the URL. Works great for something like a small backbone app.

  2. Captain says:

    Hi Matt, I have updated the tutorial to address the scenario. Thanks for the feedback. Thanks to @azat_co too!

  3. Trang says:

    Would you use res. sendFile() to show images in the public/images directory as well? Say for example to make them available in a form ( option) to be shown in a post, for example. Can res.sendFile() send multiple files or is there a better method?

  4. Captain says:

    Trang, don’t use res.sendFile(). Instead, mark ./public as a public dir, using the static middleware.
    app.use(express.static('./public'));
    Express will make everything under that load in the browser.

Make a Comment