Take a look at this post I wrote a while back. I wrote a helper that will automatically render a full or partial view in express.

The key is to create jade views like this: (unfortunately Jade views are pre-compiled and you can't pass a variable to include , nor can you conditionally call extends , so we need this "glue" file. You'll see why.)

// home_full.jade extends layout block content include home

It extends the layout file and includes a partial view. This view acts as the glue between the real view and the layout file. These intermediary views always end in "_full.jade".

Next I created my own little middleware function that adds the helper to req .

app.use(function (req, res, next) { res.renderView = function (viewName, viewModel) { res.render(viewName + req.xhr ? null : '_full', viewModel); next(); }; });

It's called renderView and it does the xhr logic for us. Instead of rendering views with req.render ...

res.render('home' + req.xhr ? null : '_full', viewModel);

...you just call req.renderView and pass in the view name:

res.renderView('home');

Now if the request is a full page request then we'll send back the fully compiled view, layout and all. If the ajax request header is set (which most client-side libraries like JQuery and others kindly do for you) then we'll send back only the partial view and let the client populate the appropriate area on the page :)

PS - If you need to send back views along with other JSON data you can use my extended version of the helper function. Example:

res.renderView = function (viewName, viewModel) { if (!req.xhr) { res.render(viewName + '_full', viewModel); } else { res.render(viewName, viewModel, function (err, view) { if (err) return next(err); res.json({ title: viewModel.title || "Untitled | CodeTunnel.com", bannerText: viewModel.bannerText || "CodeTunnel.com", view: view, url: req.url }); }); } };