Managing Content Scales with the Eleventy Data Cascade
Stop repeating the same front matter in every Markdown file. Learn how to use the Eleventy Data Cascade to manage site-wide, directory-specific, and file-level metadata efficiently.
18 Jul 2026, 18:27 UTC

The Problem: Repetitive Front Matter
When building a static site, you often find yourself repeating the same metadata across dozens of files. If every blog post needs a layout: "post", a category: "engineering", and a canonicalUrl: "https://example.com/blog/", adding these to the front matter of every single Markdown file is a maintenance risk. One change to a category name requires a find-and-replace across the entire content directory.
The solution is the Eleventy Data Cascade. Instead of treating data as something that only lives inside a file, Eleventy allows you to define data at different levels of your folder hierarchy. The "cascade" is the logic Eleventy uses to merge these sources, ensuring that the most specific piece of information always wins.
How the Cascade Resolves Data
Eleventy looks for data in a specific order of precedence. If the same variable is defined in multiple places, the lower levels in this list override the higher levels:
- Global Data: Files in the
_datafolder. These are available to every single page on the site. - Directory Data: Files that match the name of a folder. Any file inside that folder (and its subfolders) inherits this data.
- Template Front Matter: The YAML or JSON block at the top of an individual file. This is the most specific and always takes priority.
Understanding this hierarchy allows you to move static constants to the global level and shared attributes to the directory level, leaving the front matter for unique content like titles and dates.
Implementing a Tiered Data Strategy
Consider a site with a blog and a documentation section. You can structure your data to avoid repetition by using a mix of global and directory files.
1. Global Site Metadata
Create a file at _data/site.json. This is ideal for site-wide constants like the site name or social media handles.
// _data/site.json
{
"name": "TechDocs",
"baseUrl": "https://techdocs.io"
}
2. Directory-Specific Defaults
If your blog posts live in a folder named posts/, create a file named posts.json (or posts.11tydata.js) inside that same folder. Eleventy automatically associates this data with every file in that directory.
// posts/posts.json
{
"layout": "layouts/post.njk",
"category": "Technical Guides",
"tags": ["blog"]
}
3. File-Level Overrides
Now, your individual Markdown files only need the data that is unique to that specific post.
---
title: "Optimizing the Data Cascade"
date: 2026-10-10
category: "Eleventy"
---
Content goes here...
In this example, the post will use the layout and tags from posts.json, but it will override the category from "Technical Guides" to "Eleventy" because front matter has the highest precedence.
Dynamic Data with JavaScript
While JSON is great for static values, you can use .js files in the _data folder to fetch external information during the build process. This is useful for pulling in API data or generating lists dynamically.
// _data/githubUsers.js
module.exports = async function() {
const response = await fetch('https://api.github.com/users/eleventy');
const data = await response.json();
return {
username: data.login,
bio: data.bio
};
};
This data is now available in any template as {{ githubUsers.username }}.
Trade-offs and Limitations
The Data Cascade is powerful, but it can introduce "hidden' logic. When a variable is being overridden across three different levels, it can become difficult to track where a specific value is originating during debugging.
Additionally, be cautious with large JavaScript data files. Because Eleventy processes these during the initial configuration phase, performing heavy API calls or complex computations in _data files can significantly increase your build times.
Verifying Your Configuration
To verify that your cascade is working correctly, you can use a debug template. Create a temporary page and output the data object using a filter like | dump (in Nunjucks) or | json (in Liquid):
<pre>{{ site | dump }}</pre>
<pre>{{ posts | dump }}</pre>
Run your build command (e.g., npx @11ty/eleventy) and check the resulting HTML page. If the values match your expected hierarchy, your cascade is configured correctly.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.