How to make route redirect or send JSON back depending on accept headers?

I want to send JSON back if a user accesses a route and the accept headers only allow JSON, and I want to redirect a user to a page if a user accesses a route and the accept headers do not allow JSON.

My solution is very hacky, but it involves inspecting req.headers.accept and seeing whether the string contains json. If it does, I return back JSON, else, I redirect. Is there a more optimal solution?

You can try the res.format method.

res.format({
  'application/json': function(){
    res.send({ message: 'hey' });
  },

  default: function(){
    res.redirect('nojson.html');
  }
});

The method describe by cr0 is probably 'The right way'. I was unaware of this newer helper method.

That solution is about right. You can use req.get to get headers in a case insensitive manner and use regexp to check the value. Typically I use the following.

module.exports = function() {
    function(req, res, next) {
      if(req.get("accept").match(/application\/json/) === null) {
        return res.redirect(406, "/other/location");
      };
      next();
    }
}

Then this can be used as a middleware.

app.use(require("./jsonCheck")());

You could also get more elaborate with the module and redirect to a custom place by changing the exported function.

module.exports = function(location) {
    function(req, res, next) {
      if(req.get("accept").match(/application\/json/) === null) {
        return res.redirect(406, location);
      };
      next();
    }
}

and use it like this

app.use(require("./jsonRedirect")("/some.html"));