hapi — Views in hapi 9 (and above)

With the release of hapi 9, the developers stripped down hapi’s internal dependencies and removed the previously integrated vision plugin. This plugin was responsible to decorate hapi’s server object with the views method. Removing the plugin from the framework’s core resulted in losing the server.views method. Don’t worry, this breaking change doesn’t require much effort to get server.views back in hapi business.

hapi Series Overview

Views in Hapi 8 and Lower

Until hapi 8, you can define your template engine by directly passing an options object to server.views. The code below illustrates a hapi server configuration by setting handlebars as the template engine:

const hapi = require('hapi')

// Create hapi server instance
const server = new hapi.Server()

// add connection parameters
server.connection({  
  host: 'localhost',
  port: 3000
});

server.views({  
  engines: {
    html: require('handlebars')
  }
});

// configure routes, etc
// …

// Start the server
server.start(function() {  
  console.log('Server started at: ' + server.info.uri);
});

Since hapi shipped with the vision plugin integrated by default, you could directly access server.views and pass the configuration object to customize the template handling for your project.

This method doesn’t work anymore in hapi 9 and higher. The section below describes how to get the view configuration back into hapi.

Views in Hapi 9 and Higher

In hapi 9, the vision plugin was removed from the framework’s direct dependencies and therefore hapi “lost” the ability to render views with various template engines. To get the server.views method in hapi, you need to manually add the vision and inert plugins and register them with hapi. Before we dive into the framework’s configuration, let’s shortly review the depdendencies section of your package.json file.

Required depdencies for hapi 9 and higher (defined in pacakge.json)

"dependencies": {
  "hapi": "^9.3.1",
  "inert": "^3.0.1",
  "vision": "^3.0.0"
}

The snippet above only adds the current stable versions of hapi framework, inert and vision plugins as dependencies. The vision plugin is required to add template rendering support to hapi. inert handles static files and directory support for hapi. This static file and directory support is required if you want to deliver static asset files like JS, CSS or images by just defining the path to the respective directory. Hapi — precisely inert — will handle everything for you!

The following code illustrates how to configure view support in hapi 9 and higher:

hapi v17

const Hapi = require('hapi')

// Create hapi server instance
const server = new Hapi.Server({  
  host: 'localhost',
  port: 3000
})

async function liftOff() {  
  await server.register([
    {
      plugin: require('vision')  // add template rendering support in hapi
    },
    {
      plugin: require('inert')  // handle static files and directories in hapi
    }
  ])

  server.views({
    engines: {
      html: require('handlebars')
    }
  })

  try {
    await server.start()
    console.log('Server started at: ' + server.info.uri);
  } catch (err) {
    process.exit(1)
  }
}

liftOff()  

hapi v16 (till v9)

const hapi = require('hapi')

// Create hapi server instance
const server = new hapi.Server()

// add connection parameters
server.connection({  
  host: 'localhost',
  port: 3000
});

server.register([  
  {
    register: require('vision')  // add template rendering support in hapi
  },
  {
    register: require('inert')  // handle static files and directories in hapi
  }
], function(err) {
  if (err) {
    throw err;
  }

  // set view configuration in plugin register callback
  server.views({
    engines: {
        html: require('handlebars')
    }
  });
});

// configure routes, etc
// …

// Start the server
server.start(function() {  
  console.log('Server started at: ' + server.info.uri);
});

First, we need to register the vision and inert plugins to hapi. You can do this by passing an array of objects to hapi’s server.register function. Each object within the array requires at least register and optionally options properties to be defined. The register property is the plugin import and options is an individual options object to customize the plugin configuration. The example above doesn’t make use of options.

The second step is to define the view configuration. For that, use the callback function of the server.register method. Within the callback, you can finally access server.views which enables you the custom view configuration. Pass your individual options to the method and that’s it. Custom view support is back in hapi!


Addional Resources

Explore the Library

Find interesting tutorials and solutions for your problems.