Menu Close

Server-Side Development with Hapi.js — Rendering Views

Hapi.js is a small Node framework for developing back end web apps.

In this article, we’ll look at how to create back end apps with Hapi.js.

Rendering a View

We can render a view with the h.view method.

For example, we can write:

index.js

const Path = require('path');
const Hapi = require('@hapi/hapi');
const Hoek = require('@hapi/hoek');

const init = async () => {
  const server = new Hapi.Server({
    port: 3000,
    host: '0.0.0.0',
    debug: { request: ['error'] }
  });
  await server.register(require('@hapi/vision'));
  server.views({
    engines: {
      html: {
        module: require('handlebars'),
        compileMode: 'sync'
      },
    },
    relativeTo: __dirname,
    path: 'templates',
  });

  server.route({
    method: 'GET',
    path: '/',
    handler (request, h) {
      return h.view('index');
    }
  });

  await server.start();
  console.log('Server running at:', server.info.uri);
};
process.on('unhandledRejection', (err) => {
  console.log(err);
  process.exit(1);
});
init();

templates/index.html

<div>Content</div>

We have:

h.view('index')

to render the index.html file.

And we have the relativeTo property to specify where the template folder is relative to.

And path has the template folder name.

So whatever is in the index.html file is rendered.

We can pass in dynamic data to the view. For instance, we can write:

index.js

const Path = require('path');
const Hapi = require('@hapi/hapi');
const Hoek = require('@hapi/hoek');

const init = async () => {
  const server = new Hapi.Server({
    port: 3000,
    host: '0.0.0.0',
    debug: { request: ['error'] }
  });
  await server.register(require('@hapi/vision'));
  server.views({
    engines: {
      html: {
        module: require('handlebars'),
        compileMode: 'sync'
      },
    },
    relativeTo: __dirname,
    path: 'templates',
  });

  server.route({
    method: 'GET',
    path: '/',
    handler (request, h) {
      return h.view('index', { title: 'My home page' });
    }
  });

  await server.start();
  console.log('Server running at:', server.info.uri);
};
process.on('unhandledRejection', (err) => {
  console.log(err);
  process.exit(1);
});
init();

templates/index.html

<div>{{title}}</div>

We call h.view with the 2nd argument:

h.view('index', { title: 'My home page' })

The title property is rendered with {{title}} .

View Handler

We can shorten our route handler that render views with a view handler.

For example, we can write:

index.js

const Path = require('path');
const Hapi = require('@hapi/hapi');
const Hoek = require('@hapi/hoek');

const init = async () => {
  const server = new Hapi.Server({
    port: 3000,
    host: '0.0.0.0',
    debug: { request: ['error'] }
  });
  await server.register(require('@hapi/vision'));
  server.views({
    engines: {
      html: {
        module: require('handlebars'),
        compileMode: 'sync'
      },
    },
    relativeTo: __dirname,
    path: 'templates',
  });

  server.route({
    method: 'GET',
    path: '/',
    handler: {
      view: 'index'
    }
  });

  await server.start();
  console.log('Server running at:', server.info.uri);
};
process.on('unhandledRejection', (err) => {
  console.log(err);
  process.exit(1);
});
init();

We have:

server.route({
  method: 'GET',
  path: '/',
  handler: {
    view: 'index'
  }
});

to specify the view file to render instead of calling h.view .

To pass in data to the view, we write:

index.js

const Path = require('path');
const Hapi = require('@hapi/hapi');
const Hoek = require('@hapi/hoek');

const init = async () => {
  const server = new Hapi.Server({
    port: 3000,
    host: '0.0.0.0',
    debug: { request: ['error'] }
  });
  await server.register(require('@hapi/vision'));
  server.views({
    engines: {
      html: {
        module: require('handlebars'),
        compileMode: 'sync'
      },
    },
    relativeTo: __dirname,
    path: 'templates',
  });

  server.route({
    method: 'GET',
    path: '/',
    handler: {
      view: {
        template: 'index',
        context: {
          title: 'My home page'
        }
      }
    }
});

  await server.start();
  console.log('Server running at:', server.info.uri);
};
process.on('unhandledRejection', (err) => {
  console.log(err);
  process.exit(1);
});
init();

templates/index.html

<div>{{title}}</div>

We set the context.title property to pass the title to the view.

Then we render that with {{title}} .

So when we go to / , we see My home page displayed.

Conclusion

We can render views with view handlers and pass in dynamic data to Hapi views.

Posted in Hapi