Skip to navigation Skip to main content
Stable
3.0.0
Canary
3.0.1-alpha.5
Menu
Eleventy 1.93s
Next.js 70.65s

Nunjucks

Contents
Eleventy Short Name File Extension npm Package
njk .njk nunjucks

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

Nunjucks Environment Options

Jump to section titled: Nunjucks Environment Options

We use Nunjucks defaults for all environment options (shown in the configure section of the Nunjucks docs).

Optional: Use your Nunjucks Environment Options

Jump to section titled: Optional: Use your Nunjucks Environment Options

It’s recommended to use the Configuration API to override the default Nunjucks options.

eleventy.config.js
export default function (eleventyConfig) {
eleventyConfig.setNunjucksEnvironmentOptions({
throwOnUndefined: true,
autoescape: false, // warning: don’t do this!
});
};
module.exports = function (eleventyConfig) {
eleventyConfig.setNunjucksEnvironmentOptions({
throwOnUndefined: true,
autoescape: false, // warning: don’t do this!
});
};

Advanced: Use your Nunjucks Environment

Jump to section titled: Advanced: Use your Nunjucks Environment

While it is preferred and simpler to use the Options-specific API method above (new in Eleventy 1.0!)—as an escape mechanism for advanced usage you may pass in your own instance of a Nunjucks Environment using the Configuration API.

WARNING:
Not compatible with setNunjucksEnvironmentOptions above—this method will override any configuration set there.
eleventy.config.js
import Nunjucks from "nunjucks";

export default function (eleventyConfig) {
let nunjucksEnvironment = new Nunjucks.Environment(
new Nunjucks.FileSystemLoader("_includes")
);

eleventyConfig.setLibrary("njk", nunjucksEnvironment);
};
const Nunjucks = require("nunjucks");

module.exports = function (eleventyConfig) {
let nunjucksEnvironment = new Nunjucks.Environment(
new Nunjucks.FileSystemLoader("_includes")
);

eleventyConfig.setLibrary("njk", nunjucksEnvironment);
};

Supported Features

Jump to section titled: Supported Features
Feature Syntax
✅ Includes {% include 'included.njk' %} looks in _includes/included.njk. Filenames must be in quotes. Does not process front matter in the include file.
✅ Includes (Relative Path) Relative paths use ./ (template’s directory) or ../ (template’s parent directory).

Example: {% include './included.njk' %} looks for included.njk in the template’s current directory. Does not process front matter in the include file.
✅ Extends {% extends 'base.njk' %} looks in _includes/base.njk. Does not process front matter in the include file.
✅ Extends (Relative Path) Relative paths use ./ (template’s directory) or ../ (template’s parent directory)

Example: {% extends './base.njk' %} looks for base.njk in the template’s current directory. Does not process front matter in the include file.
✅ Imports {% import 'macros.njk' %} looks in _includes/macros.njk. Does not process front matter in the include file.
✅ Imports (Relative Path) Relative paths use ./ (template’s directory) or ../ (template’s parent directory):
{% import './macros.njk' %} looks for macros.njk in the template’s current directory. Does not process front matter in the include file.
✅ Filters {% name | filterName %} Read more about Filters.
Universal Filters {% name | filterName %} Read more about Filters.
Custom Tags {% uppercase name %} Read more about Custom Tags.
Shortcodes {% uppercase name %} Read more about Shortcodes.

Filters

Jump to section titled: Filters

Filters are used to transform or modify content. You can add Nunjucks specific filters, but you probably want to add a Universal filter instead.

Read more about Nunjucks Filter syntax.

eleventy.config.js
export default function(eleventyConfig) {
// Nunjucks Filter
eleventyConfig.addNunjucksFilter("myNjkFilter", function(value) { /* … */ });

// Nunjucks Asynchronous Filter (read on below)
eleventyConfig.addNunjucksAsyncFilter("myAsyncNjkFilter", function(value, callback) { /* … */ });

// Universal filters (Adds to Liquid, Nunjucks, and 11ty.js)
eleventyConfig.addFilter("myFilter", function(value) { /* … */ });
};
module.exports = function(eleventyConfig) {
// Nunjucks Filter
eleventyConfig.addNunjucksFilter("myNjkFilter", function(value) { /* … */ });

// Nunjucks Asynchronous Filter (read on below)
eleventyConfig.addNunjucksAsyncFilter("myAsyncNjkFilter", function(value, callback) { /* … */ });

// Universal filters (Adds to Liquid, Nunjucks, and 11ty.js)
eleventyConfig.addFilter("myFilter", function(value) { /* … */ });
};

Usage

Jump to section titled: Usage
<h1>{{ myVariable | myFilter }}</h1>

Multiple Filter Arguments

Jump to section titled: Multiple Filter Arguments
eleventy.config.js
export default function (eleventyConfig) {
// Nunjucks Filter
eleventyConfig.addNunjucksFilter(
"concatThreeStrings",
function (arg1, arg2, arg3) {
return arg1 + arg2 + arg3;
}
);
};
module.exports = function (eleventyConfig) {
// Nunjucks Filter
eleventyConfig.addNunjucksFilter(
"concatThreeStrings",
function (arg1, arg2, arg3) {
return arg1 + arg2 + arg3;
}
);
};
<h1>{{ "first" | concatThreeThings("second", "third") }}</h1>

Asynchronous Nunjucks Filters

Jump to section titled: Asynchronous Nunjucks Filters

By default, almost all templating engines are synchronous. Nunjucks supports some asynchronous behavior, like filters. Here’s how that works:

eleventy.config.js
export default function (eleventyConfig) {
eleventyConfig.addNunjucksAsyncFilter(
"myAsyncFilter",
function (value, callback) {
setTimeout(function () {
callback(null, "My Result");
}, 100);
}
);
};
module.exports = function (eleventyConfig) {
eleventyConfig.addNunjucksAsyncFilter(
"myAsyncFilter",
function (value, callback) {
setTimeout(function () {
callback(null, "My Result");
}, 100);
}
);
};

The last argument here is the callback function, the first argument of which is the error object and the second is the result data. Use this filter like you would any other: {{ myValue | myAsyncFilter }}.

Here’s a Nunjucks example with 2 arguments:

eleventy.config.js
export default function (eleventyConfig) {
eleventyConfig.addNunjucksAsyncFilter(
"myAsyncFilter",
function (value1, value2, callback) {
setTimeout(function () {
callback(null, "My Result");
}, 100);
}
);
};
module.exports = function (eleventyConfig) {
eleventyConfig.addNunjucksAsyncFilter(
"myAsyncFilter",
function (value1, value2, callback) {
setTimeout(function () {
callback(null, "My Result");
}, 100);
}
);
};

Multi-argument filters in Nunjucks are called like this: {{ myValue1 | myAsyncFilter(myValue2) }}.

Shortcodes

Jump to section titled: Shortcodes

Shortcodes are reusable bits of content. You can add Nunjucks specific shortcodes, but it’s probably easier to add a Universal shortcode instead.

Single Shortcode

Jump to section titled: Single Shortcode
eleventy.config.js
export default function(eleventyConfig) {
// Nunjucks Shortcode
eleventyConfig.addNunjucksShortcode("user", function(name, twitterUsername) { /* … */ });

// Universal Shortcodes (Adds to Liquid, Nunjucks, 11ty.js)
eleventyConfig.addShortcode("user", function(name, twitterUsername) {
return `<div class="user">
<div class="user_name">
${name}</div>
<div class="user_twitter">@
${twitterUsername}</div>
</div>
`
;
});
};
module.exports = function(eleventyConfig) {
// Nunjucks Shortcode
eleventyConfig.addNunjucksShortcode("user", function(name, twitterUsername) { /* … */ });

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

Nunjucks Template Usage

Jump to section titled: Nunjucks Template Usage
{% user "Zach Leatherman", "zachleat" %}

Outputs

Jump to section titled: Outputs
<div class="user">
<div class="user_name">Zach Leatherman</div>
<div class="user_twitter">@zachleat</div>
</div>

Paired Shortcode

Jump to section titled: Paired Shortcode
eleventy.config.js
export default function(eleventyConfig) {
// Nunjucks Shortcode
eleventyConfig.addPairedNunjucksShortcode("user", function(bioContent, name, twitterUsername) { /* … */ });

// Universal Shortcodes (Adds to Liquid, Nunjucks, 11ty.js)
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>
`
;
});
};
module.exports = function(eleventyConfig) {
// Nunjucks Shortcode
eleventyConfig.addPairedNunjucksShortcode("user", function(bioContent, name, twitterUsername) { /* … */ });

// Universal Shortcodes (Adds to Liquid, Nunjucks, 11ty.js)
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>
`
;
});
};

Nunjucks Usage

Jump to section titled: Nunjucks Usage

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

{% user "Zach Leatherman", "zachleat" %}
Zach likes to take long walks on Nebraska beaches.
{% enduser %}
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>

Shortcode Named Argument Syntax (Nunjucks-only)

Jump to section titled: Shortcode Named Argument Syntax (Nunjucks-only)

Creates a single argument object to pass to the shortcode.

eleventy.config.js
export default function(eleventyConfig) {
// Nunjucks Shortcode
eleventyConfig.addNunjucksShortcode("user", function (user) {
return `<div class="user">
<div class="user_name">
${user.name}</div>
${user.twitter ? `<div class="user_twitter">@${user.twitter}</div>` : ""}
</div>
`
;
});
};
module.exports = function(eleventyConfig) {
// Nunjucks Shortcode
eleventyConfig.addNunjucksShortcode("user", function (user) {
return `<div class="user">
<div class="user_name">
${user.name}</div>
${user.twitter ? `<div class="user_twitter">@${user.twitter}</div>` : ""}
</div>
`
;
});
};

Nunjucks Usage

Jump to section titled: Nunjucks Usage

The order of the arguments doesn’t matter.

{% user name="Zach Leatherman", twitter="zachleat" %}
{% user twitter="zachleat", name="Zach Leatherman" %}
Outputs
<div class="user">
<div class="user_name">Zach Leatherman</div>
<div class="user_twitter">@zachleat</div>
</div>

Nunjucks Usage

Jump to section titled: Nunjucks Usage

Importantly, this syntax means that any of the arguments can be optional (without having to pass in a bunch of null, null, null to maintain order).

{% user name="Zach Leatherman" %}
Outputs
<div class="user">
<div class="user_name">Zach Leatherman</div>
</div>

Asynchronous Shortcodes

Jump to section titled: Asynchronous Shortcodes

Note that the configuration methods here to add asynchronous shortcodes are different than their synchronous counterparts. This is just another gentle reminder here that these API methods are pretty verbose and it’s probably easier to add a Universal shortcode instead.

eleventy.config.js
export default function (eleventyConfig) {
eleventyConfig.addNunjucksAsyncShortcode(
"user",
async function (name, twitterUsername) {
return await fetchAThing();
}
);

eleventyConfig.addPairedNunjucksAsyncShortcode(
"user2",
async function (content, name, twitterUsername) {
return await fetchAThing();
}
);
};
module.exports = function (eleventyConfig) {
eleventyConfig.addNunjucksAsyncShortcode(
"user",
async function (name, twitterUsername) {
return await fetchAThing();
}
);

eleventyConfig.addPairedNunjucksAsyncShortcode(
"user2",
async function (content, name, twitterUsername) {
return await fetchAThing();
}
);
};

Nunjucks Usage

Jump to section titled: Nunjucks Usage

This is identical to the synchronous Nunjucks usage.

{% user "Zach Leatherman", "zachleat" %}

{% user2 "Zach Leatherman", "zachleat" %}
Zach likes to take long walks on Nebraska beaches.
{% enduser2 %}

Warning: set is not async-friendly

Jump to section titled: Warning: set is not async-friendly
WARNING:
This is a Common Pitfall.

Nunjucks’ {% set %} tag does not work to capture asynchronous content (e.g. asynchronous shortcodes).

Starting in Eleventy v1.0.0, Eleventy provides a {% setAsync %} tag to work around this limitation. Notably and contrary to set, setAsync’s first argument is a string.

{% setAsync "myVariableName" %}
{% myAsyncShortcode %}
{% endsetAsync %}

<!-- Now use the variable -->
{{ myVariableName }}

Access to Eleventy supplied data

Jump to section titled: Access to Eleventy supplied data

You can access page, eleventy, ctx, and env in filters and shortcodes. Read more on the Shortcodes and Filters documentation.

Generic Global

Jump to section titled: Generic Global

Nunjucks provides a custom way to add globals to templates. These can be any arbitrary JavaScript: functions, variables, etc. Note that this is not async-friendly (Nunjucks does not support await inside of templates).

eleventy.config.js
export default function (eleventyConfig) {
eleventyConfig.addNunjucksGlobal("fortythree", 43);
};
module.exports = function (eleventyConfig) {
eleventyConfig.addNunjucksGlobal("fortythree", 43);
};
{{ fortythree }}
eleventy.config.js
export default function (eleventyConfig) {
eleventyConfig.addNunjucksGlobal("fortytwo", function () {
return 42;
});
};
module.exports = function (eleventyConfig) {
eleventyConfig.addNunjucksGlobal("fortytwo", function () {
return 42;
});
};
{{ fortytwo() }}

Read more on the Nunjucks documentation or relevant discussion on Eleventy Issue #1060.


Other pages in Template Languages:


Jump to section titled: Related Docs