Labs ICT
Pro Login

Middleware and Views

Using middleware with EJS views.

Global Data with app.locals

When you need data available in every template across your entire application, app.locals is the place to put it. This is perfect for site-wide settings, user info, or configuration values.


app.locals.siteName = 'My Awesome App';
app.locals.year = new Date().getFullYear();
    

These values are now accessible in any EJS file without passing them explicitly.


<footer>
  <p>© <%= year %> <%= siteName %></p>
</footer>
    
Try it Yourself →

Request-Specific Data with res.locals

While app.locals persists across requests, res.locals is scoped to a single request. Use it for data that changes per request, like the current user or flash messages.


app.use((req, res, next) => {
  res.locals.currentUser = req.user || null;
  res.locals.success = req.flash('success');
  res.locals.error = req.flash('error');
  next();
});
    

Now every template in the request cycle has access to these values.


<% if (currentUser) { %>
  <p>Welcome back, <%= currentUser.name %>!</p>
<% } %>

<% if (success.length) { %>
  <div class="alert"><%= success %></div>
<% } %>
    
Try it Yourself →

Middleware that Adds Data to Templates

You can create custom middleware that injects data into every template. This keeps your routes clean and your data logic centralized.


app.use((req, res, next) => {
  res.locals.navItems = [
    { name: 'Home', path: '/' },
    { name: 'About', path: '/about' },
    { name: 'Contact', path: '/contact' }
  ];
  next();
});
    

Your navigation template can now use this data without any route-level configuration.


<nav>
  <% navItems.forEach(item => { %>
    <a href="<%= item.path %>"><%= item.name %></a>
  <% }); %>
</nav>
    

Flash Messages Pattern

Flash messages provide temporary feedback to users after actions like form submissions or authentication. Combined with EJS, they create a smooth user experience.


const flash = require('express-flash');
app.use(flash());

app.post('/login', (req, res) => {
  req.flash('success', 'Logged in successfully!');
  res.redirect('/dashboard');
});
    

Display flash messages in your layout template so they appear on any page.


<% if (locals.success && success.length) { %>
  <div class="flash success">
    <%= success %>
  </div>
<% } %>

<% if (locals.error && error.length) { %>
  <div class="flash error">
    <%= error %>
  </div>
<% } %>
    
Try it Yourself →

Combining Multiple Middleware

You can stack multiple middleware functions to build up template data progressively. Each one adds or modifies data before the template renders.


app.use(setGlobalData);
app.use(setUserData);
app.use(setNavigationData);

app.get('/', (req, res) => {
  res.render('home');
});
    

This layered approach keeps your code modular and easy to maintain. Each middleware handles one responsibility.


<div class="layout">
  <%- include('partials/nav') %>
  <main><%- body %></main>
  <%- include('partials/footer') %>
</div>