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.

  <b>Keep in touch with mama kin</b>
  <i>You say goodbye, and I say hello</i>

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.

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.

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 or HAProxy 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.


  1. Express.js - express.static
  2. Express.js - res.sendFile
  3. NGINX
  4. HAProxy