nunjucks, express, node

Nunjucks and Express app

Implementing Nunjucks in an Express app

In this article we will be setting up our Express application to use Nunjucks templating engine. Both Nunjucks and Express are part of our standard NodeJS application stack.

The short answer

For advanced users below is the short answer with only the core code, skipping all the Express boilerplate

app.js (without boilerplate)

let  express = require('express')
let  nunjucks = require('nunjucks')

let  app = express()
let  router = express.Router()

nunjucks.configure('views', {
  autoescape:  true,
  express:  app
})

router.get('/', async  function(req, res, next) {
  let  data = {
    message: 'Hello world!',
    layout:  'layout.njk',
    title: 'Nunjucks example'
  }

  res.render('index.njk', data)
})

and the two Nunjucks files:

views/layout.njk

<!doctype html>
<html  lang="en">
  <head>
    <title>{{ title }}</title>
  </head>
  <body>
    {% block  content %}
    {% endblock %}
  </body>
</html>

views/index.njk

{% extends  layout %}
{% block  content %}
  <h1>{{message}}</h1>
{% endblock %}

The full answer

Express

Express is a minimal and flexible Node web application framework that provides a robust set of features for web and mobile applications. Express is our first choice as an unopinionated framework and it has a very light footprint, very broad following and huge number of useful packages.

Nunjucks

Is a rich and powerful templating language with block inheritance, autoescaping, macros, asynchronous control, and long list of standard tags. We prefer Nunjucks over alternatives mainly due to its most complete feature set. Support from Mozilla also guarantees longevity of the framework.

Create an Express app

We will use an Express app generator to create a standard Express app boilerplate. Nunjucks is not one of the standard templating engines available in the generator, so we are going to use --no-view option to skip the automated templating engine installation. We will add Nunjucks manually later. Let's create the standard app in myapp directory:

npx express-generator myapp --no-view

Go to /public directory and remove index.html file which is there as a placeholder since we haven't selected any view engine.

Install Nunjucks

Go to `myapp directory and install Nunjucks. We prefer to use Yarn as a package manager as it provides more stable installations for large repositories. See this article on why it is worth using yarn over npm. The command below will also install all other required packages:

cd myapp
yarn add nunjucks

Configure Nunjucks

In app.js we need to require Nunjucks package:

let  nunjucks = require('nunjucks')

and set up Nunjucks configuration passing on the Express app into the config object. We set views to be our directory for templates and layouts:

nunjucks.configure('views', {
  autoescape:  true,
  express:  app
})

The full app.js file should look like this now:

let  express = require('express')
let  path = require('path')
let  cookieParser = require('cookie-parser')
let  logger = require('morgan')
let  nunjucks = require('nunjucks')

let  indexRouter = require('./routes/index')
let  usersRouter = require('./routes/users')

let  app = express()

// configute Nunjucks with 'views' as templates directory
nunjucks.configure('views', {
  autoescape:  true,
  express:  app
})

app.use(logger('dev'))
app.use(express.json())
app.use(express.urlencoded({ extended:  false }))
app.use(cookieParser())
app.use(express.static(path.join(__dirname, 'public')))

app.use('/', indexRouter)
app.use('/users', usersRouter)

module.exports = app

We have the basic Nunjucks configured. Now we just need to add the views directory with a sample template and a layout and render our new template with some data.

Create Nunjucks layout and template files

Create a layout file views/layout.njk:

<!doctype html>
<html  lang="en">
  <head>
    <title>{{ title }}</title>
  </head>
  <body>
    {% block  content %}
    {% endblock %}
  </body>
</html>

Create a template file `views/index.njk:`

{% extends  layout %}
{% block  content %}
  <h1>{{message}}</h1>
{% endblock %}

There are some useful features in the above two files worth highlighting:

  • {{ title }} - this is a basic variable declaration, basic stuff you expect from any templating system
  • {% block content %} - this is a declaration of a content block to support template inheritance
  • {% extends layout %} - this is used to specify which file the template should feed into (extend). This declaration supports both a static string as a name of the file, but in our, more advanced example, we are actually using a variable layout which is passed to the template and allows for dynamic declaration of template inheritance. In our example below we will simply pass 'layout.njk' as a value here but you could name your templates in any other way and have multiple different top level layouts to use in your application

Pass data and render content

Got to routes/index.js and add a data object with a message "Hello world!", a title and specify the file name to use as a layout. Finally, call the render function with the index.njk as a template passing on the data object.

The full routes/index.js should look like this:

let  express = require('express')
let  router = express.Router()

router.get('/', async  function(req, res, next) {
  let  data = {
    message: 'Hello world!',
    layout:  'layout.njk',
    title: 'Nunjucks example'
  }

  res.render('index.njk', data)
})

module.exports = router

Test

Go back to console and run the Express app

yarn start

Go to: http://localhost:3000/ - you should see Hello world! messsage

Powered by

Node
Github
Copyright 2019 - present