Skip to navigation Skip to main content
Eleventy
Eleventy Documentation
Stable
3.0.0
Toggle Menu
Eleventy 1.93s
Next.js 70.65s

Custom Data File Formats

Contents

Out of the box, Eleventy supports arbitrary JavaScript and JSON for both template and directory data files as well as global data.

Maybe you want to add support for TOML or YAML too! Any text format will do.

Note that you can also add Custom Front Matter Formats as well.

Usage

eleventy.config.js
export default function (eleventyConfig) {
// Receives file contents, return parsed data
eleventyConfig.addDataExtension("yml,yaml", (contents, filePath) => {
return {};
});
};
module.exports = function (eleventyConfig) {
// Receives file contents, return parsed data
eleventyConfig.addDataExtension("yml,yaml", (contents, filePath) => {
return {};
});
};
  • Added in v2.0.0 Pass a comma-separated list of extensions.
  • Added in v2.0.0 filePath was added as a second argument.

Usage with Options Added in v2.0.0

eleventy.config.js
export default function (eleventyConfig) {
// or with options (new in 2.0)
eleventyConfig.addDataExtension("fileExtension", {
parser: (contents, filePath) => ({}),

// defaults are shown:
read: true,
encoding: "utf8",
});
};
module.exports = function (eleventyConfig) {
// or with options (new in 2.0)
eleventyConfig.addDataExtension("fileExtension", {
parser: (contents, filePath) => ({}),

// defaults are shown:
read: true,
encoding: "utf8",
});
};
  • parser: the callback function used to parse the data. The first argument is the data file’s contents (unless read: false). The second argument is the file path Added in v2.0.0.
  • read (default: true): use read: false to change the parser function’s first argument to be a file path string instead of file contents.
  • encoding (default: "utf8"): use this to change the encoding of Node’s readFile. Use null if you want a Buffer.

Examples

YAML

Here we’re using the js-yaml package. Don’t forget to npm install js-yaml.

eleventy.config.js
import yaml from "js-yaml";

export default function (eleventyConfig) {
eleventyConfig.addDataExtension("yaml", (contents) => yaml.load(contents));
};
const yaml = require("js-yaml");

module.exports = function (eleventyConfig) {
eleventyConfig.addDataExtension("yaml", (contents) => yaml.load(contents));
};

TOML

Here we’re using the @iarna/toml package. Don’t forget to npm install @iarna/toml.

eleventy.config.js
import toml from "@iarna/toml";

export default function (eleventyConfig) {
eleventyConfig.addDataExtension("toml", (contents) => toml.parse(contents));
};
const toml = require("@iarna/toml");

module.exports = function (eleventyConfig) {
eleventyConfig.addDataExtension("toml", (contents) => toml.parse(contents));
};

Adding a custom JSON file extension

eleventy.config.js
export default function (eleventyConfig) {
eleventyConfig.addDataExtension("geojson", (contents) =>
JSON.parse(contents)
);
};
module.exports = function (eleventyConfig) {
eleventyConfig.addDataExtension("geojson", (contents) =>
JSON.parse(contents)
);
};

Feed EXIF image data into the Data Cascade

Added in v2.0.0 This uses the exifr package to read image EXIF data. Don’t forget to npm install exifr.

Note that the second argument is an object with a parser function.

eleventy.config.js
import exifr from "exifr";

export default function (eleventyConfig) {
eleventyConfig.addDataExtension("png,jpeg", {
parser: async (file) => {
let exif = await exifr.parse(file);

return {
exif,
};
},

// Using `read: false` changes the parser argument to
// a file path instead of file contents.
read: false,
});
};
const exifr = require("exifr");

module.exports = function (eleventyConfig) {
eleventyConfig.addDataExtension("png,jpeg", {
parser: async (file) => {
let exif = await exifr.parse(file);

return {
exif,
};
},

// Using `read: false` changes the parser argument to
// a file path instead of file contents.
read: false,
});
};
  • Example using a template data file:
    • Given my-blog-post.md and my-blog-post.jpeg then exif will be available for use in my-blog-post.md (e.g. {{ exif | log }})
  • Example using a global data file:
    • Given _data/images/custom.jpeg then images.custom.exif will be available for use on any template (e.g. {{ images.custom.exif | log }})

Ordering in the Data Cascade

Note that in the data cascade there is a specific conflict resolution order when the same keys are used in data files. For example, JavaScript files take priority over JSON. These new custom data file formats are treated as lower priority than both JavaScript and JSON.

If you add multiple file extensions, the latter ones take priority over the earlier ones. In the following example, if there is ever conflicting data between *.toml and *.yaml files, the yaml file will take precedence.

eleventy.config.js
import toml from "@iarna/toml";
import yaml from "js-yaml";

export default function (eleventyConfig) {
// Lower priority
eleventyConfig.addDataExtension("toml", (contents) => toml.parse(contents));

// Higher priority
eleventyConfig.addDataExtension("yaml", (contents) => yaml.load(contents));
};
const toml = require("@iarna/toml");
const yaml = require("js-yaml");

module.exports = function (eleventyConfig) {
// Lower priority
eleventyConfig.addDataExtension("toml", (contents) => toml.parse(contents));

// Higher priority
eleventyConfig.addDataExtension("yaml", (contents) => yaml.load(contents));
};

Example

Consider the template data file search for a my-first-blog-post.md file. The order with custom toml and yaml formats (as seen above) will go as follows:

  • my-first-blog-post.11tydata.js
  • my-first-blog-post.11tydata.json
  • my-first-blog-post.11tydata.yaml (custom)
  • my-first-blog-post.11tydata.toml (custom)
  • my-first-blog-post.json
  • my-first-blog-post.yaml (custom)
  • my-first-blog-post.toml (custom)

This same ordering would be used for template directory data files as well.


Other pages in Using Data: