Skip to content


Subversion checkout URL

You can clone with
Download ZIP


res.locals overrides 'options' passed to view engine function #1386

defunctzombie opened this Issue · 10 comments

3 participants


The view engine function has the following prototype:

fn(path, options, cb);

Options would be an object which contains the settings(which are the app settings) and also the locals. However, if you set locals using res.locals.settings = something then these locals are also added to this object and in the case I just described will override the app settings.

Either this object is not really the options (which it seems like it is) or the settings of the locals should not be overriding the properties of this object.


After some discussion on IRC, the reason this happens this way is to allow for options and locals to be passed via res.render(.., { options/locals }); without having to do { locals: {} }

Not sure how common it is to pass additional options versus just locals. Something to also consider is the impact on template engines if anything is changed here. I suppose this is something to think about for express 4.0 (if that ever happens).

At the very least the overriding behavior should probably be documented under res.locals and in res.engine

tj commented

yeah it's not super common from the ones I'm familiar with at least, with jade you might pass { debug: true } from time to time. .filename is passed by express so we could work that out internally anyway, we may be able to refactor this a bit without busting much stuff, but it would require engines to take another object

tj commented

or alter their current behaviour if we attach .locals


Please stop polluting users object with application level data. Stuff like cache:true, settings, _locals has nothing to do in the template scope.

Possible solutions:

  • Move all application level stuff to an own namespace in the data. F.e.

    res.render('abc', {a: 1});
    // would result in
        a: 1,
        express: {
            settings: {
                'x-powered-by': true,
                 env: 'development',
                 views: '/Users/kof/work/projects/kof/jqtpl/test/fixtures/1',
                 'jsonp callback name': 'callback',
                 'json spaces': 2,
                 'view engine': 'html'
            _locals: [Function: locals],
            cache: false
  • Prefix stuff like settings, cache, 'locals' with '_' to avoid conflicts. Only user defined locals can be merged.

  • Pass all application level stuff as a separate object and let template engine decide what to do with it.
tj commented

IMO one object is worth the small gotcha, when's the last time you wanted to do if (cache) in a template, probably never because in-template caching doesn't make sense unless you're rails. Settings exposed by default is arguable but will remain in 3x for BC regardless


you never know what "cache" could mean in user application layer, it can be f.e. an interface for something technical, where cache variable just echoing the current state of application caching setting ... or whatever .... its really bad idea to fuck with user objects.

tj commented

sure, it's a tradeoff between res.render(view, { locals }, { options }, [fn]) and what we have now, not something we can change for now, overall not something im too concerned with, we can adjust in 4x if needed


locals which are defined by the user is less a problem compared to stuff like settings and cache which is unexpected for the user.


for me locals, which a user has defined is fine to be merged with user data.

tj commented

settings isn't an issue at all since it's defined on initialization, you can override it with app.locals, res.locals or res.render()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.