Skip to navigation Skip to main content
11ty Logo Sustainability Fundraising
Eleventy
Eleventy Documentation
Stable
2.0.1
Canary
3.0.0-alpha.13
Toggle Menu
Eleventy 1.93s
Gatsby 29.05s

Shortcodes

Contents

Various template engines can be extended with shortcodes for easy reusable content. This is sugar around Template Language Custom Tags. Shortcodes are supported in JavaScript, Liquid, Nunjucks, and Handlebars templates.

Here are a few examples:

Liquid Nunjucks 11ty.js Handlebars
Filename sample.liquid
{% user firstName, lastName %}

The comma between arguments is optional in Liquid templates.

Filename sample.liquid
{% user firstName lastName %}
Filename sample.njk
{% user firstName, lastName %}

The comma between arguments is required in Nunjucks templates.

Filename sample.11ty.js
module.exports = function({ firstName, lastName }) {
return `<h1>${this.user(firstName, lastName)}</h1>`;
};
Filename sample.hbs
<!-- Note the three opening and closing curly brackets (the triple-stash) -->
{{{ user firstName lastName }}}
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, e.g. {{{ shortcodeName }}}) to avoid double-escaped HTML. If it’s double-escaped a paragraph tag may render as &lt;p&gt;
Filename .eleventy.js
module.exports = function(eleventyConfig) {
// Shortcodes added in this way are available in:
// * Markdown
// * Liquid
// * Nunjucks
// * Handlebars (not async)
// * JavaScript

eleventyConfig.addShortcode("user", function(firstName, lastName) {});

// Async support for `addShortcode` is new in Eleventy v2.0.0
eleventyConfig.addShortcode("user", async function(myName) { /* … */ });

// Async method available
eleventyConfig.addAsyncShortcode("user", async function(myName) { /* … */ });
};

A shortcode returns content (a JavaScript string or template literal) that is used in the template. You can use these however you’d like—you could even think of them as reusable components.

INFO:
Markdown files are pre-processed as Liquid templates by default—any shortcodes available in Liquid templates are also available in Markdown files. Likewise, if you change the template engine for Markdown files, the shortcodes available for that templating language will also be available in Markdown files.

Read more about using shortcodes on the individual Template Language documentation pages:

Paired Shortcodes Jump to heading

The shortcodes we saw above were nice, I suppose. But really, they are not all that different from a filter. The real ultimate power of Shortcodes comes when they are paired. Paired Shortcodes have a start and end tag—and allow you to nest other template content inside!

Liquid Nunjucks 11ty.js Handlebars
Syntax Liquid
{% user firstName, lastName %}
Hello {{ someOtherVariable }}.

Hello {% anotherShortcode %}.
{% enduser %}

The comma between arguments is optional in Liquid templates.

Syntax Nunjucks
{% user firstName, lastName %}
Hello {{ someOtherVariable }}.

Hello {% anotherShortcode %}.
{% enduser %}

The comma between arguments is required in Nunjucks.

Syntax Handlebars
{{#user firstName lastName}}
Hello
{{someOtherVariable}}. Hello
{{anotherShortcode}}.
{{/user}}
module.exports = function (data) {
let userContent = `Hello ${data.someOtherVariable}

Hello
${this.anotherShortCode()}`
;

// pass the content as the first parameter.
return `<h1>${this.user(userContent, data.firstName, data.lastName)}</h1>`;
};

When adding paired shortcodes using the Configuration API, the first argument to your shortcode callback is the nested content.

Filename .eleventy.js
module.exports = function(eleventyConfig) {
// Shortcodes added in this way are available in:
// * Markdown
// * Liquid
// * Nunjucks
// * Handlebars (not async)
// * JavaScript

eleventyConfig.addPairedShortcode("user", function(content, firstName, lastName) {});

// Async support for `addPairedShortcode` is new in Eleventy v2.0.0
eleventyConfig.addPairedShortcode("user", async function(content, myName) { /* … */ });

// Async method available
eleventyConfig.addPairedAsyncShortcode("user", async function(content, myName) { /* … */ });
};
INFO:
Markdown files are pre-processed as Liquid templates by default—any shortcodes available in Liquid templates are also available in Markdown files. Likewise, if you change the template engine for Markdown files, the shortcodes available for that templating language will also be available in Markdown files.

Read more about using paired shortcodes on the individual Template Language documentation pages:

Asynchronous Shortcodes Jump to heading

This is supported by Liquid, Nunjucks, and JavaScript template types (Handlebars is not async-friendly).

Filename .eleventy.js
module.exports = function (eleventyConfig) {
// Async support for `addShortcode` and `addPairedShortcode` is new in Eleventy v2.0.0
eleventyConfig.addShortcode("single", async function (myName) {
/* … */
});
eleventyConfig.addPairedShortcode("paired", async function (content, myName) {
/* … */
});

// Async methods available in Eleventy v0.10.0+
eleventyConfig.addAsyncShortcode("single", async function (myName) {
/* … */
});
eleventyConfig.addPairedAsyncShortcode(
"paired",
async function (content, myName) {
/* … */
}
);
};

Scoped Data in Shortcodes Jump to heading

A few Eleventy-specific data properties are available to shortcode callbacks.

Filename .eleventy.js
module.exports = function (eleventyConfig) {
// Make sure you’re not using an arrow function here: () => {}
eleventyConfig.addShortcode("myShortcode", function () {
// this.page
// this.eleventy
});
};

Per-Engine Shortcodes Jump to heading

You can also specify different functionality for shortcodes in each engine, if you’d like. Using the addShortcode or addPairedShortcode function is equivalent to adding the shortcode to every supported template engine.

Filename .eleventy.js
module.exports = function(eleventyConfig) {
// Liquid
eleventyConfig.addLiquidShortcode("user", function(firstName, lastName) {});
eleventyConfig.addPairedLiquidShortcode("user", function(content, firstName, lastName) {});

// Nunjucks
eleventyConfig.addNunjucksShortcode("user", function(firstName, lastName) {});
eleventyConfig.addPairedNunjucksShortcode("user", function(content, firstName, lastName) {});

// Handlebars
eleventyConfig.addHandlebarsShortcode("user", function(firstName, lastName) {});
eleventyConfig.addPairedHandlebarsShortcode("user", function(content, firstName, lastName) {});

// JavaScript Template Function (New in 0.7.0)
eleventyConfig.addJavaScriptFunction("user", function(firstName, lastName) {});
eleventyConfig.addJavaScriptFunction("user", function(content, firstName, lastName) {}); // Faux-paired shortcode
INFO:
Markdown files are pre-processed as Liquid templates by default—any shortcodes available in Liquid templates are also available in Markdown files. Likewise, if you change the template engine for Markdown files, the shortcodes available for that templating language will also be available in Markdown files.

Async Friendly Per-Engine Shortcodes Jump to heading

Learn more about these on the individual template engine pages for Nunjucks, Liquid, and 11ty.js JavaScript.

Filename .eleventy.js
  // Async-friendly
// Liquid is already async-friendly
eleventyConfig.addLiquidShortcode("user", async function() {});
eleventyConfig.addPairedLiquidShortcode("user", async function(content) {});

// Nunjucks Async
eleventyConfig.addNunjucksAsyncShortcode("user", async function() {});
eleventyConfig.addPairedNunjucksAsyncShortcode("user", async function(content) {});

// JavaScript Template Function (make sure you `await` these!)
eleventyConfig.addJavaScriptFunction("user", async function() {});
eleventyConfig.addJavaScriptFunction("user", async function(content) {}); // Faux-paired shortcode
};

Other pages in Configuration:


Related Docs