Last Updated: February 25, 2016
·
4.39K
· bripkens

node.js static web server for Single-Page Applications which use the History API

When developing Single-Page Applications that are using the History API, you have a problem with common development servers like grunt server or python -m SimpleHTTPServer: When refreshing the page your browser assumes that your current location is actually referring to a real file und thus requests it from the server, which, obviously, is not existing.

To cope with this you can use the following node.js code which shows how node-static (npm install node-static --save-dev) is used to serve static files while falling back to /index.html whenever a file is not of a specific static resource type.

/*global module:false,require:false,console:false */
var webroot = "./target";
var port = 8000;
var assetTypes = [".js", ".css", ".txt", ".ico", ".html", ".png"];

var nodeStatic = require("node-static");
var http = require("http");
var util = require("util");

function isStaticResource(url) {
  return assetTypes.reduce(function(memo, assetType) {
    return memo || url.indexOf(assetType) !== -1;
  }, false);
}

module.exports.startServer = function() {
  var file = new(nodeStatic.Server)(webroot, {
    cache: 0
  });

  http.createServer(function(req, res) {
    req.addListener("end", function() {
      if (!isStaticResource(req.url)) {
        req.url = "/index.html";
      }

      file.serve(req, res, function(err, result) {
        if (err) {
          console.error("Error serving %s - %s", req.url, err.message);
          res.writeHead(err.status, err.headers);
          res.end();
        }
      });
    });
  }).listen(port);

  console.log("Development server running at http://localhost:%d", port);
};