The Equal Justice Initiative
Eleventy
The possum is Eleventy’s mascot
Eleventy Documentation
Menu
Eleventy 1.93s
Next.js 70.65s

Handlebars

Template Languages:

Contents

Eleventy Short Name File Extension npm Package
hbs .hbs handlebars.js

You can override a .hbs file’s template engine. Read more at Changing a Template’s Rendering Engine.

Handlebars Options Jump to heading

Optional: Set your own Library instance Jump to heading

As an escape mechanism for advanced usage, pass in your own instance of the Handlebars library using the Configuration API.

module.exports = function(eleventyConfig) {
let handlebars = require("handlebars");
eleventyConfig.setLibrary("hbs", handlebars);
};

Supported Features Jump to heading

Feature Syntax
✅ Partials {{> user}} looks for _includes/user.hbs. Does not process front matter in the include file.
🚫 Partials (Relative Path) Not yet supported: {{> ./user}} looks for user.hbs in the template’s current directory.
✅ Helpers (Custom Tags) {{ helperName myObject }} Handlebars calls them Helpers, but Eleventy calls them Shortcodes. Read more about Shortcodes or Custom Tags.
Eleventy Universal Filters {{ filterName myObject }} Read more about Filters.
Shortcodes {{{ uppercase name }}} Read more about Shortcodes.

Helpers Jump to heading

Helpers are used to transform or modify content. You can add Handlebars specific helpers, but you probably want to add a Universal shortcode instead.

Read more about Handlebars Helpers syntax

module.exports = function(eleventyConfig) {
// Handlebars Helper
eleventyConfig.addHandlebarsHelper("myHandlebarsHelper", function(value) {});

// Universal filters (Adds to Liquid, Nunjucks, and Handlebars)
// Read the note about Universal Filters below: Use a shortcode instead!
eleventyConfig.addFilter("myFilter", function(value) {});
};

Usage Jump to heading

<h1>{{{ myHandlebarsHelper myVariable }}}</h1>
INFO:
Note that if you return HTML in your Handlebars helper, you need to use the Handlebars triple-stash syntax (three opening and three closing curly brackets) to avoid double-escaped HTML.

Asynchronous Helpers Jump to heading

These are not supported by Handlebars. Read more at this Handlebars issue.

A note about Universal Filters Jump to heading

Universal filters have always been funneled into Handlebars helpers. However, shortcodes (Paired/Single) match better with the semantic footprint of Handlebars Helpers.

module.exports = function(eleventyConfig) {
// Universal filters (Adds to Liquid, Nunjucks, and Handlebars)
eleventyConfig.addFilter("myFilter", function(value) {});
};

Moving forward for Handlebars content, using Universal Shortcodes are preferred to Universal Filters. We will continue to support funneling Universal filters to Handlebars helpers. This will not affect your template content as the syntax for Handlebars filters/helpers/shortcodes will continue to be the same. They’re all just helpers.

Shortcodes Jump to heading

Shortcodes are basically reusable bits of content. You can add Handlebars specific shortcodes, but you probably want to add a Universal shortcode instead.

Single Shortcode Jump to heading

module.exports = function(eleventyConfig) {
// Handlebars Shortcode
eleventyConfig.addHandlebarsShortcode("user", function(name, twitterUsername) {});

// Universal Shortcodes (Adds to Liquid, Nunjucks, Handlebars)
eleventyConfig.addShortcode("user", function(name, twitterUsername) {
return `<div class="user">
<div class="user_name">
${name}</div>
<div class="user_twitter">@
${twitterUsername}</div>
</div>
`
;
});
};

Usage Jump to heading

{{{ user "Zach Leatherman" "zachleat" }}}
INFO:
Note that if you return HTML in your Handlebars shortcode, you need to use the Handlebars triple-stash syntax (three opening and three closing curly brackets) to avoid double-escaped HTML.
Outputs
<div class="user">
<div class="user_name">Zach Leatherman</div>
<div class="user_twitter">@zachleat</div>
</div>

Paired Shortcode Jump to heading

module.exports = function(eleventyConfig) {
// Handlebars Shortcode
eleventyConfig.addPairedHandlebarsShortcode("user", function(bioContent, name, twitterUsername) {});

// Universal Shortcodes (Adds to Liquid, Nunjucks, Handlebars)
eleventyConfig.addPairedShortcode("user", function(bioContent, name, twitterUsername) {
return `<div class="user">
<div class="user_name">
${name}</div>
<div class="user_twitter">@
${twitterUsername}</div>
<div class="user_bio">
${bioContent}</div>
</div>
`
;
});
};

Usage Jump to heading

Note that you can put any Handlebars tags or content inside the {{ user }} shortcode! Yes, even other shortcodes!

{{# user "Zach Leatherman" "zachleat" }}
Zach likes to take long walks on Nebraska beaches.
{{/ user }}
INFO:
While unpaired shortcodes and helpers required that you use the Handlebars triple-stash syntax (three opening and three closing curly brackets) to avoid double-escaped HTML, paired Handlebars shortcodes do not have this requirement.
Outputs
<div class="user">
<div class="user_name">Zach Leatherman</div>
<div class="user_twitter">@zachleat</div>
<div class="user_bio">Zach likes to take long walks on Nebraska beaches.</div>
</div>

Asynchronous Shortcodes Jump to heading

These are not supported by Handlebars. Read more at this Handlebars issue.

Access to page data values Jump to heading

If you aren’t using an arrow function, Handlebars Shortcodes (and Nunjucks, Liquid, and 11ty.js JavaScript Functions) will have access to Eleventy page data values without needing to pass them in as arguments.

module.exports = function(eleventyConfig) {
eleventyConfig.addHandlebarsShortcode("myShortcode", function() {
// Available in 0.11.0 and above
console.log( this.page );

// For example:
console.log( this.page.url );
console.log( this.page.inputPath );
console.log( this.page.fileSlug );
});
};

Other pages in Template Languages:


Related Docs