Display a static html file with koa.js

tomet picture tomet · Jun 3, 2014 · Viewed 25.4k times · Source

What I want to do is serve the index.html file when the index route (i.e. localhost:3000) is called.

I use koa-router for routing, so my route looks like this:

app.all("/", function * (next){
    //Send the file here
});

I tried to use koa-static like this:

var serve = require('koa-static');
 app.all("/", function * (next){
        serve("index.html");
    });

But that didn't work. Then I tried to use co-views (I put the html file in the public directory now):

var views = require("co-views");
var render = views("public");
app.all("/", function * (next){
    this.status = 200;
    this.body = yield render("index.html");
});

But that didn't work.

So can anyone tell me what I have to do?

Answer

Hugo Dozois picture Hugo Dozois · Jun 9, 2014

Well there are a few ways to do it, here's two of them.

Templating engine

The simplest way is probably to use a templating engine like swig or jade to serve the file.

To install it do :

npm install -s swig

In order to do it with co-views, just do

var views = require("co-views");
var render = views("public", { map: { html: 'swig' });
app.all("/", function * (next){
  this.body = yield render("index");
}); 

Plain file system

Or if you don't want to use a templating engine you can use the plain Node File System library.

In order to be able to use it with yield, you have to wrap the function in a promise.

var fs = require('fs');

var readFileThunk = function(src) {
  return new Promise(function (resolve, reject) {
    fs.readFile(src, {'encoding': 'utf8'}, function (err, data) {
      if(err) return reject(err);
      resolve(data);
    });
  });
}

app.use(router.get('/', function *(){
  this.body = yield readFileThunk(__dirname + '/public/htmlfilename.html');
}));

Also, note that if you use koa-static, and you put index.html in your public folder (the folder you link to koa-static), it's going to serve index.html by default on the root url without any code. This is a convention.