First HandlebarsJS Web Part in SPFx

My last blog post focused on the general installation and configuration of Handlebars together with SPFx. I haven’t explained much on the code I used. Now it’s time to go more into detail how to deal with Handlebar templates and the overall code of the web part.

Location of templates in project

As I mentioned in a previous blog post, I like to separate the web part code from reusable components. Therefore I create a ‘templates’ folder in the ‘src’ directory.

Templatefolder in SPFx Project

The default web part comes already with a predefined content, so I gave it a try to convert it into a Handlebar template. The first step was to copy the content into a new file named ‘HelloWorld.hbs’. This file is not ready yet to be used as a template it needs to be slightly adopted.

Modify default content for Handlebars

Inside the content, two different type of elements needs differently. Those are the style definitions and the variable that render the data of the web part.

Style Definitions

The style definitions are prefixed with a $-sign and encapsulated in curly brackets.

<div class="${styles.helloWorld}">
<div class="${styles.container}">

To make it replaceable for handlebar, remove the $-sign and encapsulate the variable with additional curly brackets.

<div class="{{styles.helloWorld}}">
<div class="{{styles.container}}">

Now Handlebars can replace the style variable with the defined and prefixed value.


Like the style definitions, all variables are prefixed with the $-sign and encapsulated with single curly brackets.

<p class="ms-font-l ms-fontColor-white">${escape(}</p>

Again replace the $-sign and double the curly brackets. Also, remove the ‘escape’ function that wraps the variable name. The result of this cleanup is the code below.

<p class="ms-font-l ms-fontColor-white">{{}}</p>

The ‘escape’ function URL encode the string stored in the variable, and Handlebars will manage this. Especially this function can cause problems in future because browser sooner or later won’t support this deprecated JavaScript feature anymore. Instead, ‘encodeURI’ or ‘encodeURIComponent’ are better options.
Now that all the code have been cleaned up and prepared for Handlebars the code looks as shown below.

<div class="{{styles.helloWorld}}">
<div class="{{styles.container}}">
<div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white {{styles.row}}">
<div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
<span class="ms-font-xl ms-fontColor-white">Welcome to SharePoint!</span>
<p class="ms-font-l ms-fontColor-white">Customize SharePoint experiences using Web Parts.</p>
<p class="ms-font-l ms-fontColor-white">{{description}}</p>
<a href="" class="{{styles.button}}">
<span class="{{styles.label}}">Learn more</span>

View on Github

Use template in web part

The final step is to make use of the template directly in the web part. Already defined in the file ‘config.json’ is the location of the external Handlebars library.
The import statement below makes sure that it loads during the initialization of the web part.

// Importing handlebars
import * as Handlebars from 'handlebars';

View on GitHub

The second thing is to load the template.

// load and precompile template
var HelloWorldTemplate = <HandlebarsTemplateDelegate>require('../../templates/HelloWorld.hbs');

View on GitHub

In general, require imports external files to your code. With the handlebar loader in place, Before the ‘require’ statement loads the file, the webpack Handlebar loader, precompiles the template and returns a HandlebarsTemplateDelegate. In other words, the template is a JavaScript function. You can pass the data to this function, and it returns an HTML string, ready to be added to the page.

Define data

Now we need to set data for the template. In this simple case, it is an easy task.

// bind data to template
var data = {
styles: styles,

View on GitHub

The ‘data’ JSON object contains two attributes. The ‘style’ attribute directly pass the existing style information of the web part through. The ‘description’ attribute pass the web part description property to the template.

Generate HTML code from template

Now that the data we like to pass to the template are in place we can create the content of the web part.

// compile and add template
this.domElement.innerHTML = HelloWorldTemplate(data);

View on GitHub

The only thing left to do is to assign the resulting HTML to the innerHTML of the web part. Now the web part looks like this.

Final Handlebar Web Part

Final things to consider

Handlebars per se is a front end library and can be used directly in the browser. It might take some time and cause potentially slow loading of the web part. The recommended way it to precompile the templates and only bind data to the templates in your web part.
My SimpleStyle Style Guide application is based on Handlebars too to make it as open as possible and allows you to add additional frameworks. During the development of the first beta version, I had to deal with approximately 130 different templates. All those were loaded during the initial page load and took about two seconds.
After switching to precompiled templates, I reduced the loading time down to 50 to 60 milliseconds.
Even when it is not likely that you load that many templates in your web part, from my point of view, the handlebars web pack loader are the better way to do it.

Get this solution from GitHub




Sharing ideas about art, design, web and development. I'm a professional #SharePoint consultant and developer. Microsoft Community Contributor Award 2011/2012

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

2020년 8월 WITH News Letter

Learning ReactJS — Day 1

Power of XPath expressions in Oracle Integration Cloud

Integration looks like this

Nextjs Data fetching methods

Using the adapter pattern for external libraries.

Angular and Redux — Part 2

🌍 Creating React usePosition() hook for getting browser’s geolocation

The JavaScript Cheatsheet you need in 2021

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Stefan Bauer

Stefan Bauer

Sharing ideas about art, design, web and development. I'm a professional #SharePoint consultant and developer. Microsoft Community Contributor Award 2011/2012

More from Medium

When your focus is fading…

Size and Scale Fluid Typography with CSS Clamp

Size and Scale Fluid Typography with CSS Clamp

Improve your Storybook workflows with Chromatic

How Lean justifies a Landing Page as product.