Take the 2-minute tour ×

I'm using Express.js (on Node.js) and I know that you can render a view with custom data via the "locals" parameter. (res.render("template", { locals: { foo: "bar" } });)

Is there any way to have "globals"? (ie. data that's accessible to every view)

I saw view options, but that isn't recursive, so it replaces the locals I set if I use any locals with my template.

This is my use case: I want to make it so that CSS/JS files can be added on a per-page basis, and that is part of my main layout. The problem is, if I don't explicitly set those arrays on every render, I get an undefined error, so in my template I always have to do the typeof css !== "undefined" dance. Additionally, I have other select box option lists that I don't want to have to explicitly add to each of my forms.

share|improve this question
couldn't you do it by defining a variable with a global scope (like by your require statements) and then referencing it inside one of your app.get calls? –  Stephen Jan 18 '11 at 20:24
Yes, but then I still have to explicitly pass that data in on every single call of render(). –  Dominic Barnes Jan 18 '11 at 21:38
LOL! I found myself searching for this solution, and here I am again in the shoes you were in back in Jan. Thanks for asking this question! –  Stephen Aug 11 '11 at 22:48
add comment

6 Answers

up vote 24 down vote accepted

It's worth noting for those who may have come across this question since the release of Express 3, that the method 'dynamicHelpers' no longer exists.

Instead you can use the app.locals function, which acts as an object you can store values or functions in, and then makes them available to views. For example:-

// In your app.js etc.
app.locals.title = "My App";
    version: 3,
    somefunction: function() {
        return "function result";

// Then in your templates (shown here using a jade template)


// Will output

My App
function result

If you need access to the request object to pull information from, you can write a simple middle-ware function and use the app.settings variable.

For example, if you are using connect-flash to provide messages to your users, you might do something like this:

app.use(function(req, res, next) {
    app.set('error', req.flash('error'));

Which would give you access to the error message with =settings.error in your template.

These topics are covered here, albeit slightly briefly: http://expressjs.com/api.html#app.locals

share|improve this answer
Best explanation I've found yet. And I've scoured. Thanks. –  Josh Pinter Jan 29 '13 at 5:10
app.set('error', msg) would set error for the ENTIRE application, not just the user making the request, or am I wrong? –  vegetable Aug 27 '13 at 10:51
Your explaination is fantastic. But when I try to display the global variables in my Jade file by using "=title", nothing appeared. For this, I should use the following synthax "#{title}" to display correctly my variable. –  JohnDoe66 Mar 12 at 19:41
add comment

There is a way to have "global" variables for views, using dynamic view helpers.

From the Express.js guide:


Registers dynamic view helpers. Dynamic view helpers are simply functions which accept req, res, and are evaluated against the Server instance before a view is rendered. The return value of this function becomes the local variable it is associated with.

app.dynamicHelpers({ session: function(req, res){ return req.session; } });

All views would now have session available so that session data can be accessed via session.name etc:

<%= session.name %>

You can find a real example on how to use them here: https://github.com/alessioalex/Nodetuts/tree/master/express_samples (node app.js to start the app)

share|improve this answer
This worked wonders for me, thanks! +1 –  talentedmrjones Nov 9 '11 at 4:03
add comment

A real-world example of using view options as the author mentioned:

var app = express.createServer();

app.configure(function() {
  app.set('views', path.join(__dirname, '..', 'views'));
  app.set('view engine', 'jade');
  app.set('view options', {
    assetVersion: 1

And then in my layout.jade (base template for the app in my case):

link(rel='stylesheet', href='/static/css/' + assetVersion + '/style.css')
script(src='/static/js/' + assetVersion + '/script.js')

With this little trick, I only have to update the assetVersion variable one place to make sure that my assets aren’t cached in Varnish or other places.

share|improve this answer
add comment

I wound up looking into the source code, and I've actually found that this is now possible in never versions of Express. (so far, only available through GitHub)

share|improve this answer
Would you mind sharing a link to the source you found? I'm trying to do the same thing. Thanks. –  luisgo May 12 '11 at 17:16
The version out there now (v2+) allows for app.set("view options", { ...default values... }); –  Dominic Barnes May 12 '11 at 17:56
@dominic what are those default values? or at least where are they listed? –  talentedmrjones Sep 14 '11 at 20:38
add comment

The simplest way to accomplish this is to create a variable that represents the default set of locals for your views. Then create a function that accepts an object, merges it with the locals, and returns the merged object.

I also pass ALL my locals inside a container object i.e. {locals:{g:{prop:val}}} so in my views I can refernce g.prop which will just return null when it isn't set, instead of throwing an undefined error.

function default_page_vars(custom_vars){
    var vars = {
        footer: true,
        host: req.headers.host.split(':')[0],
        config: this.config

        for(var k in custom_vars){
            vars[k] = custom_vars[k];
    return {

//within your handler
response.render(view, {
    locals: default_page_vars(other_locals)
share|improve this answer
add comment

This is a buried response, but I finally got it to work.

1) This is an example around the module connect-flash

2) Add a piece of middleware in server.js/app.js to add req to locals. This allows the template to call request.flash() whenever it needs. Without this, flash() gets consumed on each request/redirect defeating the purpose.

var app = module.exports = express()
  , flash=require('connect-flash');
  app.use(express.session({ secret: "shhh" }));

  // Start Router
  app.use(function(req, res, next) {
    res.locals.request = req;


3) Setup your route as normal (this is coffeescript, but nothing special)

app.get '/home', (req, res) ->
  req.flash "info", "this"
  res.render "#{__dirname}/views/index"

4) Call request.flash() when you want the messages. They are consumed on each call, so don't console.log them or they'll be gone :-)

    title= config.appTitle
    include partials/_styles

    include partials/_scripts

      a(href="/logout") Logout CURRENTUSER
      h2= config.appTitle

      - var flash = request.flash()
      each flashType in ['info','warn','error']
        if flash[flashType]
            = flash[flashType]

    block content
      h1 content here
share|improve this answer
I recommend not passing the whole request object. //always include flash app.use(function(req, res, next) { res.locals.flasher = {} ; res.locals.flasher.flash = req.flash; res.locals.flasher.session = req.session; next(); }); –  Setheron Dec 26 '13 at 21:53
add comment

Your Answer


