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.