Taming Metadata Redundancy with the Eleventy Data Cascade
Stop repeating metadata in every Markdown file. Learn how to use the Eleventy Data Cascade to manage global, directory, and page-level data efficiently.
13 Aug 2026, 13:45 UTC

The Metadata Maintenance Trap
When scaling a static site, you often hit a wall where you are manually adding the same metadata—like a category name, a layout path, or a social media handle—to dozens of individual Markdown files. Updating a single shared attribute across 50 pages becomes a tedious find-and-replace operation that is prone to human error.
The solution is the Eleventy Data Cascade. Instead of treating every page as an isolated island of data, the cascade allows you to define metadata at different levels of your project hierarchy. Eleventy merges these levels during the build process, ensuring that the most specific data always wins.
How the Cascade Resolves Data
Eleventy processes data in a specific order of priority. If the same key (e.g., title) exists in multiple places, the cascade resolves it from the most general to the most specific:
- Global Data: Files in the
_datafolder. These are available to every single page on the site. - Directory Data: Files prefixed with a dot (e.g.,
posts.json) located within a specific folder. These apply to every file in that folder and its subfolders. - Template Front Matter: The YAML or JSON block at the top of an individual file. This has the highest priority and overrides everything else.
Practical Implementation: A Blog Structure
Consider a site with a global site name, a shared layout for all blog posts, and unique titles for each post. Here is how to configure the cascade to avoid repetition.
1. Global Site Data
Create a file at _data/site.json. This data is automatically available to all templates without imports.
{
"name": "Engineering Insights",
"baseUrl": "https://example.com"
}
2. Directory-Specific Data
Instead of adding layout: posts to every Markdown file in your /posts folder, create a directory data file. Name it after the folder (e.g., posts/posts.json).
{
"layout": "layouts/post.njk",
"category": "Technical Guides"
}
3. Page-Level Overrides
In an individual file like posts/hello-world.md, you only need to define the unique content. However, if this specific post belongs to a different category, the front matter will override the directory data.
---
title: Hello World
category: Announcements
---
This is my first post using the data cascade!
Comparing Data Resolution
Based on the configuration above, here is how Eleventy resolves the final data object for hello-world.md:
| Key | Global Value | Directory Value | Front Matter | Final Resolved Value |
|---|---|---|---|---|
name |
Engineering Insights | - | - | Engineering Insights |
layout |
- | layouts/post.njk | - | layouts/post.njk |
category |
- | Technical Guides | Announcements | Announcements |
Trade-offs and Debugging
While the cascade reduces redundancy, it introduces data opacity. When your project grows to include deeply nested folders, it can become difficult to track exactly where a specific value is being inherited from.
Limitations to consider:
- Build Performance: Using
.jsfiles in_dataallows for dynamic API fetching, but these run during the build. Complex asynchronous calls can significantly slow down your compilation time. - Naming Sensitivity: If you name your directory data file incorrectly (e.g.,
posts/data.jsoninstead ofposts/posts.json), Eleventy will ignore it, and your pages will lack the necessary layouts.
Verifying the Cascade
To verify your data is resolving correctly, you can use the debug filter in a Nunjucks template to print the entire data object for a page:
<pre>{{ debug }}
</pre>
Run your local build command (usually npx @11ty/eleventy --serve) and inspect the page source. If a value isn't appearing, check that your directory data file matches the folder name exactly.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.