Managing Shared State with the Eleventy Data Cascade
Learn how to use the Eleventy Data Cascade to eliminate redundancy by structuring shared data across global, directory, and page levels.
18 Apr 2026, 05:12 UTC

The Problem: Data Duplication in Static Sites
When building a static site, you often find yourself repeating the same metadata—like the site name, social media handles, or navigation links—across dozens of templates. Hard-coding these values leads to a maintenance nightmare; changing a single link requires a find-and-replace across the entire project.
The Eleventy Data Cascade solves this by creating a deterministic hierarchy of data. Instead of importing data into every file, Eleventy automatically merges data from global, directory, and page-level sources, ensuring that the most specific value always wins.
How the Cascade Hierarchy Works
Eleventy resolves data in a specific order. If a piece of data is defined in multiple places, the lower levels in this list override the higher levels:
- Global Data: Files located in the root
_datafolder. These are available to every single page in the project. - Directory Data: Files (like
posts.json) located within a specific folder. Every page in that folder and its subfolders inherits this data. - Template Data: Data defined in the front matter of an individual file or a companion JSON/JS file with the same name as the template.
This structure allows you to define a site-wide theme in global data, a specific layout for a blog category in directory data, and a unique title in the page front matter.
Worked Example: Implementing a Multi-Level Configuration
Consider a site with a global brand identity and a specific "Guides" section that needs its own metadata.
1. Global Data (Root Level)
Create _data/site.json to hold universal constants:
{
"title": "TechDocs Central",
"footerText": "© 2026 TechDocs",
"theme": "light"
}
2. Directory Data (Section Level)
In your /guides/ folder, create a guides.json file. This ensures every page in the guides directory knows it belongs to that section:
{
"sectionName": "User Guides",
"theme": "blue"
}
3. Page Data (Individual Level)
In /guides/install.md, use front matter to define the specific page title:
---
title: "Installation Guide"
---
# Welcome to the Install Guide
The Resulting Data Object
When Eleventy processes install.md, the resolved data object looks like this:
| Key | Resolved Value | Source |
|---|---|---|
title |
"Installation Guide" | Page Front Matter |
theme |
"blue" | Directory Data (Overrides Global) |
footerText |
"© 2026 TechDocs" | Global Data |
sectionName |
"User Guides" | Directory Data |
Trade-offs and Limitations
While the cascade is powerful, it introduces two primary risks: shadowing and recursion overhead.
Shadowing occurs when a key in a page-level file accidentally matches a key in a global file. Because the page-level data wins, the global value is completely replaced. If your global data is a complex object and you override it with a simple string at the page level, you lose access to all other properties in that global object for that specific page.
Recursion Overhead: In very large sites (thousands of pages) with deeply nested _data folders or circular references in JavaScript data files, the resolution process can slow down build times. Eleventy must calculate the merge for every single page during the build phase.
Verification and Debugging
To verify that your cascade is resolving as expected, you can use the --debug flag during your build process. Run the following command in your terminal:
npx @11ty/eleventy --debug
Check the terminal output for data resolution logs. If a value isn't appearing, verify that the _data folder is in the correct directory relative to your input path. Remember that only files in _data folders or front matter are part of the cascade; standard JavaScript imports inside your templates bypass this system entirely.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.