[node.js] How to create global variables accessible in all views using Express / Node.JS?

Ok, so I have built a blog using Jekyll and you can define variables in a file _config.yml which are accessible in all of the templates/layouts. I am currently using Node.JS / Express with EJS templates and ejs-locals (for partials/layouts. I am looking to do something similar to the global variables like site.title that are found in _config.yml if anyone is familiar with Jekyll. I have variables like the site's title, (rather than page title), author/company name, which stay the same on all of my pages.

Here is an example of what I am currently doing.:

exports.index = function(req, res){
    res.render('index', { 
        siteTitle: 'My Website Title',
        pageTitle: 'The Root Splash Page',
        author: 'Cory Gross',
        description: 'My app description',
        indexSpecificData: someData
    });
};

exports.home = function (req, res) {
    res.render('home', {
        siteTitle: 'My Website Title',
        pageTitle: 'The Home Page',
        author: 'Cory Gross',
        description: 'My app description',
        homeSpecificData: someOtherData
    });
};

I would like to be able to define variables like my site's title, description, author, etc in one place and have them accessible in my layouts/templates through EJS without having to pass them as options to each call to res.render. Is there a way to do this and still allow me to pass in other variables specific to each page?

This question is related to node.js express sails.js template-engine ejs

The answer is


One way to do this by updating the app.locals variable for that app in app.js

Set via following

var app = express();
app.locals.appName = "DRC on FHIR";

Get / Access

app.listen(3000, function () {
    console.log('[' + app.locals.appName + '] => app listening on port 3001!');
});

Elaborating with a screenshot from @RamRovi example with slight enhancement.

enter image description here


You can do this by adding them to the locals object in a general middleware.

app.use(function (req, res, next) {
   res.locals = {
     siteTitle: "My Website's Title",
     pageTitle: "The Home Page",
     author: "Cory Gross",
     description: "My app's description",
   };
   next();
});

Locals is also a function which will extend the locals object rather than overwriting it. So the following works as well

res.locals({
  siteTitle: "My Website's Title",
  pageTitle: "The Home Page",
  author: "Cory Gross",
  description: "My app's description",
});

Full example

var app = express();

var middleware = {

    render: function (view) {
        return function (req, res, next) {
            res.render(view);
        }
    },

    globalLocals: function (req, res, next) {
        res.locals({ 
            siteTitle: "My Website's Title",
            pageTitle: "The Root Splash Page",
            author: "Cory Gross",
            description: "My app's description",
        });
        next();
    },

    index: function (req, res, next) {
        res.locals({
            indexSpecificData: someData
        });
        next();
    }

};


app.use(middleware.globalLocals);
app.get('/', middleware.index, middleware.render('home'));
app.get('/products', middleware.products, middleware.render('products'));

I also added a generic render middleware. This way you don't have to add res.render to each route which means you have better code reuse. Once you go down the reusable middleware route you'll notice you will have lots of building blocks which will speed up development tremendously.


For Express 4.0 I found that using application level variables works a little differently & Cory's answer did not work for me.

From the docs: http://expressjs.com/en/api.html#app.locals

I found that you could declare a global variable for the app in

app.locals

e.g

app.locals.baseUrl = "http://www.google.com"

And then in your application you can access these variables & in your express middleware you can access them in the req object as

req.app.locals.baseUrl

e.g.

console.log(req.app.locals.baseUrl)
//prints out http://www.google.com

With the differents answers, I implemented this code to use an external file JSON loaded in "app.locals"

Parameters

{
    "web": {
        "title" : "Le titre de ma Page",
        "cssFile" : "20200608_1018.css"
    }
}

Application

var express     = require('express');
var appli       = express();
var serveur     = require('http').Server(appli);

var myParams    = require('./include/my_params.json');
var myFonctions = require('./include/my_fonctions.js');

appli.locals = myParams;

EJS Page

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <title><%= web.title %></title>
    <link rel="stylesheet" type="text/css" href="/css/<%= web.cssFile %>">
</head>

</body>
</html>

Hoping it will help


What I do in order to avoid having a polluted global scope is to create a script that I can include anywhere.

// my-script.js
const ActionsOverTime = require('@bigteam/node-aot').ActionsOverTime;
const config = require('../../config/config').actionsOverTime;
let aotInstance;

(function () {
  if (!aotInstance) {
    console.log('Create new aot instance');
    aotInstance = ActionsOverTime.createActionOverTimeEmitter(config);
  }
})();

exports = aotInstance;

Doing this will only create a new instance once and share that everywhere where the file is included. I am not sure if it is because the variable is cached or of it because of an internal reference mechanism for the application (that might include caching). Any comments on how node resolves this would be great.

Maybe also read this to get the gist on how require works: http://fredkschott.com/post/2014/06/require-and-the-module-system/


In your app.js you need add something like this

global.myvar = 100;

Now, in all your files you want use this variable, you can just access it as myvar


you can also use "global"

Example:

declare like this :

  app.use(function(req,res,next){
      global.site_url = req.headers.host;   // hostname = 'localhost:8080'
      next();
   });

Use like this: in any views or ejs file <% console.log(site_url); %>

in js files console.log(site_url);


Examples related to node.js

Hide Signs that Meteor.js was Used Querying date field in MongoDB with Mongoose SyntaxError: Cannot use import statement outside a module Server Discovery And Monitoring engine is deprecated How to fix ReferenceError: primordials is not defined in node UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib error running php after installing node with brew on Mac internal/modules/cjs/loader.js:582 throw err DeprecationWarning: Buffer() is deprecated due to security and usability issues when I move my script to another server Please run `npm cache clean`

Examples related to express

UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block jwt check if token expired Avoid "current URL string parser is deprecated" warning by setting useNewUrlParser to true MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017] npm notice created a lockfile as package-lock.json. You should commit this file Make Axios send cookies in its requests automatically What does body-parser do with express? SyntaxError: Unexpected token function - Async Await Nodejs Route.get() requires callback functions but got a "object Undefined" How to redirect to another page in node.js

Examples related to sails.js

How to create global variables accessible in all views using Express / Node.JS? Node.js Web Application examples/tutorials

Examples related to template-engine

React.js: Wrapping one component into another How to create global variables accessible in all views using Express / Node.JS? Truncate string in Laravel blade templates How to use underscore.js as a template engine? how to reference a YAML "setting" from elsewhere in the same YAML file? Is there a template engine for Node.js?

Examples related to ejs

How to redirect to another page in node.js How can I include css files using node, express, and ejs? Loop through JSON in EJS adding .css file to ejs How to create global variables accessible in all views using Express / Node.JS? Can I use conditional statements with EJS templates (in JMVC)? Error: Cannot find module 'ejs' Node.js - EJS - including a partial