Skip to navigation Skip to main content
Stable
3.0.0
Canary
3.0.1-alpha.5
Menu
Eleventy 1.93s
Gatsby 29.05s

JavaScript

Contents
Eleventy Short Name File Extension Version Added
11ty.js .11ty.js *
11ty.js .11ty.cjs 0.11.0
11ty.js .11ty.mjs 3.0.0

Eleventy supports many different types of JavaScript content that will be parsed as Eleventy templates. They are comprehensively described below.

Raw Values

Jump to section titled: Raw Values

Raw values will not have access to Data or JavaScript Template Functions. Use a function that returns a value instead.

String

Jump to section titled: String
export default "<p>Zach</p>";
module.exports = "<p>Zach</p>";

Or template literals:

export default `<p>These can
span
multiple
lines!</p>
`
;
module.exports = `<p>These can
span
multiple
lines!</p>
`
;

Buffer

Jump to section titled: Buffer

Some templating libraries return Buffers (e.g. viperHTML).

export default Buffer.from("<p>Zách</p>");
module.exports = Buffer.from("<p>Zách</p>");

Promise

Jump to section titled: Promise
export default new Promise((resolve, reject) => {
setTimeout(function () {
resolve("<p>Zach</p>");
}, 1000);
});
module.exports = new Promise((resolve, reject) => {
setTimeout(function () {
resolve("<p>Zach</p>");
}, 1000);
});

Function

Jump to section titled: Function

Can return any raw value (e.g. String, Buffer, Promise). Use template literals to embed data values without having to concatenate strings!

export default function (data) {
return `<p>${data.name}</p>`;
};
module.exports = function (data) {
return `<p>${data.name}</p>`;
};

De-structuring syntax is a little bit easier to read:

export default function ({ name }) {
return `<p>${name}</p>`;
};
module.exports = function ({ name }) {
return `<p>${name}</p>`;
};

Maybe you like arrow functions:

export default ({ name }) => `<p>${name}</p>`;
module.exports = ({ name }) => `<p>${name}</p>`;

async functions work too:

const getAnAsyncThing = require("./lib/asyncThing");

export default async function (data) {
return `<p>${await getAnAsyncThing()}</p>`;
};
const getAnAsyncThing = require("./lib/asyncThing");

module.exports = async function (data) {
return `<p>${await getAnAsyncThing()}</p>`;
};

Classes

Jump to section titled: Classes

Eleventy looks for classes that have a render method and uses render to return the content of the template. render methods can be async.

render can return any raw value (e.g. String, Buffer, Promise).

class Test {
// or `async render({name}) {`
render({ name }) {
return `<p>${name}</p>`;
}
}

export default Test;
class Test {
// or `async render({name}) {`
render({ name }) {
return `<p>${name}</p>`;
}
}

module.exports = Test;

Optional data Method

Jump to section titled: Optional data Method
INFO:
Front Matter is not supported in JavaScript template types. Use data methods instead! Additionally, there are more alternative options in the Data Cascade.

This data acts as Front Matter for the template and similarly to Front Matter will take precedence over all other data in the data cascade. The data method can be asynchronous async data() or it can be a getter get data().

class Test {
// or `async data() {`
// or `get data() {`
data() {
return {
name: "Ted",
layout: "teds-rad-layout",
// … other front matter keys
};
}

render({ name }) {
// will always be "Ted"
return `<p>${name}</p>`;
}
}

export default Test;
class Test {
// or `async data() {`
// or `get data() {`
data() {
return {
name: "Ted",
layout: "teds-rad-layout",
// … other front matter keys
};
}

render({ name }) {
// will always be "Ted"
return `<p>${name}</p>`;
}
}

module.exports = Test;
Jump to section titled: Permalinks

The permalink data key will work here. Permalinks can be a raw value (e.g. String, Buffer, Promise) or a Function that returns any raw value.

Jump to section titled: Permalink String
class Test {
data() {
return {
// Writes to "/my-permalink/index.html"
permalink: "/my-permalink/",
};
}

render(data) {
/* … */
}
}

export default Test;
class Test {
data() {
return {
// Writes to "/my-permalink/index.html"
permalink: "/my-permalink/",
};
}

render(data) {
/* … */
}
}

module.exports = Test;
Jump to section titled: Permalink Function

Permalink Functions can return any raw value (e.g. String, Buffer, Promise).

class Test {
data() {
return {
key: "hello",
// Writes to "/my-permalink/hello/index.html"
permalink: (data) => `/my-permalink/${data.key}/`,
};
}

render(data) {
/* … */
}
}

export default Test;
class Test {
data() {
return {
key: "hello",
// Writes to "/my-permalink/hello/index.html"
permalink: (data) => `/my-permalink/${data.key}/`,
};
}

render(data) {
/* … */
}
}

module.exports = Test;
Jump to section titled: Permalink Function using a Filter

Universal filters, shortcodes, and other JavaScript Template Functions work here and are exposed on this. Read more about Eleventy provided Universal Filters.

class Test {
data() {
return {
title: "This is my blog post title",
// Writes to "/this-is-my-blog-post-title/index.html"
permalink: function (data) {
return `/${this.slug(data.title)}/`;
},
};
}

render(data) {
/* … */
}
}

export default Test;
class Test {
data() {
return {
title: "This is my blog post title",
// Writes to "/this-is-my-blog-post-title/index.html"
permalink: function (data) {
return `/${this.slug(data.title)}/`;
},
};
}

render(data) {
/* … */
}
}

module.exports = Test;

Markdown and JavaScript

Jump to section titled: Markdown and JavaScript

Yes, you can use JavaScript as your preprocessor language for Markdown. Read more about templateEngineOverride.

class Test {
data() {
return {
myName: "Zach",
templateEngineOverride: "11ty.js,md",
};
}

render(data) {
return `# This is ${data.myName}`;
}
}

export default Test;
class Test {
data() {
return {
myName: "Zach",
templateEngineOverride: "11ty.js,md",
};
}

render(data) {
return `# This is ${data.myName}`;
}
}

module.exports = Test;
INFO:
While templateEngineOverride: 11ty.js,md works to add markdown support, the special behavior of JavaScript templates does not allow other template engines to be supported here (e.g. templateEngineOverride: njk,md). One workaround is to use the Render Plugin.

JavaScript Template Functions

Jump to section titled: JavaScript Template Functions

A JavaScript Template Function allows you to extend your JavaScript templates with extra functionality. If you add any Universal Filters or Shortcodes, they will be exposed as JavaScript Template Functions.

eleventy.config.js
export default function(eleventyConfig) {
eleventyConfig.addJavaScriptFunction("myFunction", function(a, b) { /* … */ });
};
module.exports = function(eleventyConfig) {
eleventyConfig.addJavaScriptFunction("myFunction", function(a, b) { /* … */ });
};
js-fn-example.11ty.js
export default function (data) {
return `<h1>${this.myFunction(data.a, data.b)}</h1>`;
};
module.exports = function (data) {
return `<h1>${this.myFunction(data.a, data.b)}</h1>`;
};

Asynchronous JavaScript Template Functions

Jump to section titled: Asynchronous JavaScript Template Functions

This works the same as any async JavaScript function or function that returns a Promise.

This is the same as the example above but adds async before the function.

eleventy.config.js
export default function(eleventyConfig) {
eleventyConfig.addJavaScriptFunction("myAsyncFunction", async function(a, b) { /* … */ });
};
module.exports = function(eleventyConfig) {
eleventyConfig.addJavaScriptFunction("myAsyncFunction", async function(a, b) { /* … */ });
};

This is the same as the example above but adds await before the function is called.

Filename js-async-fn-example.11ty.js
export default async function (data) {
return `<h1>${await this.myAsyncFunction(data.a, data.b)}</h1>`;
};
module.exports = async function (data) {
return `<h1>${await this.myAsyncFunction(data.a, data.b)}</h1>`;
};

Warning about Arrow Functions

Jump to section titled: Warning about Arrow Functions
WARNING:
Note that by definition (read on MDN) arrow functions do not have access to this, so any use of JavaScript Functions inside of an arrow function template will throw an error.
Filename js-arrow-fn-example.11ty.js
export default (data) => {
// Using `this` in an arrow function will throw an error!
return `<h1>${this.myFunction(data.a, data.b)}</h1>`;
};
module.exports = (data) => {
// Using `this` in an arrow function will throw an error!
return `<h1>${this.myFunction(data.a, data.b)}</h1>`;
};

Relationship to Filters and Shortcodes

Jump to section titled: Relationship to Filters and Shortcodes

Any universal filters or shortcodes will also be available as JavaScript Template Functions.

eleventy.config.js
export default function(eleventyConfig) {
// Universal filters (Adds to Liquid, Nunjucks, 11ty.js)
eleventyConfig.addFilter("myFilter", function(myVariable) { /* … */ });

// Universal Shortcodes (Adds to Liquid, Nunjucks, 11ty.js)
eleventyConfig.addShortcode("user", function(firstName, lastName) { /* … */ });

// Universal Paired Shortcodes (Adds to Liquid, Nunjucks, 11ty.js)
eleventyConfig.addPairedShortcode("pairedUser", function(content, firstName, lastName) { /* … */ });
};
module.exports = function(eleventyConfig) {
// Universal filters (Adds to Liquid, Nunjucks, 11ty.js)
eleventyConfig.addFilter("myFilter", function(myVariable) { /* … */ });

// Universal Shortcodes (Adds to Liquid, Nunjucks, 11ty.js)
eleventyConfig.addShortcode("user", function(firstName, lastName) { /* … */ });

// Universal Paired Shortcodes (Adds to Liquid, Nunjucks, 11ty.js)
eleventyConfig.addPairedShortcode("pairedUser", function(content, firstName, lastName) { /* … */ });
};
Filename universal-examples.11ty.js
export default function (data) {
return `
<h1>
${this.myFilter(data.myVar)}</h1>
<p>
${this.user(data.firstName, data.lastName)}</p>
<p>
${this.pairedUser(
`Here is some more content`,
data.firstName,
data.lastName
)}
</p>
`
;
};
module.exports = function (data) {
return `
<h1>
${this.myFilter(data.myVar)}</h1>
<p>
${this.user(data.firstName, data.lastName)}</p>
<p>
${this.pairedUser(
`Here is some more content`,
data.firstName,
data.lastName
)}
</p>
`
;
};

Access to page data values

Jump to section titled: Access to page data values

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

eleventy.config.js
export default function (eleventyConfig) {
eleventyConfig.addJavaScriptFunction("myFunction", 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);
});
};
module.exports = function (eleventyConfig) {
eleventyConfig.addJavaScriptFunction("myFunction", 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:


Jump to section titled: Related Docs