Tag Archives: handlebars

Sharing Handlebars Templates on Both Server & Client in Node.js / Express with Webpack

Whilst React and Angular have become more or less ubiquitous in developing Node.js web applications, Handlebars often gets overlooked as an effective templating engine.

It’s very simple to use, isn’t overburdened with features (and code) you don’t need and is very flexible with the ability to write custom helpers.

In my last job it was used as the main templating engine and had been tooled very effectively to make it easy to use. However after leaving that organisation and doing a little project for myself I was struggling with how to best set up handlebars templates that could be used on the client as well as the server.

Google wasn’t particularly helpful – lot’s of precompiling and script tags, whereas I was keen to use Webpack to bundle up the client side assets. So once I’d figured it out I thought I would write this blog post to remind myself in future and perhaps help others.

File Structure

I’m going to assume that you have set up your node.js / express app, so will just highlight the areas that impact the handlebars and webpack set-up. This is not a complete structure, but focuses in on the key elements that I’ll be covering.

.
├── client
| └── src
| └── main.js
├── views
| ├── layouts
| └── main.html
| ├── partials
| ├── shared
| └── my-shared-template.html
| └── home.html
├── app.js
├── package.json
└── webpack.config.js

Packages Required

You’ll need to install three packages via your package manager (NPM or YARN etc.).

Setting Up The Handlebars Instance For Server Rendering

In app.js you should set up express and handlebars as follows;

Key elements here are that a handlebars instance (hbs) has been created with some configuration options;
defaultLayout: this is an express-handlebars concept of a page wrapper, see express-handlebars documentation for more detail.
extname: have set this to html rather than use the default of handlebars. This setting needs to be followed through in the set-up of the view engine.
partialsDir: it would have defaulted to views/partials, however as I want to share one or more partials on the client, I have created a views/shared folder to store shared partials, so have registered both directories with the handlebars instance.

Then the view engine is set up, using html as our file type and our handlebars instance’s engine (hbs.engine).

So now when the server is started and we navigate to the base url, the views/home.html template will be rendered, within the views/layouts/main.html wrapper.

Setting Up Webpack For Client Side Templating

to enable the handlebars shared templates to be used on the client side, a loader is needed in the webpack configuration.

The webpack.config.js should be set up like this;

The entry and output is set up to webpack the main javascript bundle, in which the shared handlebars template is referenced (more explanation on this below).
The handlebars-loader has been added to take .html files from the views/shared directory and make them available to the webpacked javascript.

Using the Handlebars Template on the Client

So now that the configuration has been done, the template can now be used on the client in the following way in the client/src/main.js file;

This is a very basic example to demonstrate rendering the template into the page with some data. It is more likely that the template data would be retrieved via an api for example, but hopefully you get the idea.

Summary

Whilst this isn’t covered very effectively in various documentation, it is very straightforward to do. From there on you can take advantage of the full feature set of handlebars. Drop me a line if you have any questions or leave a comment below.