Cutting Front‑Matter Duplication in Eleventy with Data Cascades
Eleventy’s data cascade lets you write shared values once in global, directory, or template data files, eliminating repetitive front‑matter and simplifying site maintenance. This guide walks through a concrete example, explains merge rules, and highlights trade‑offs.
28 Sept 2026, 06:40 UTC

Problem: Repetitive Front‑Matter Everywhere
When a site grows, many Markdown files end up with the same front‑matter keys—title, layout, author, tags, etc. Editing one page’s front‑matter to change a global value (like the site title) means hunting every file for that key. Drift is common: some pages get the new value, others keep the old one, and a site‑wide change can become a maintenance nightmare.
Thesis: Eleventy’s Data Cascade Lets You Write Once, Use Everywhere
Eleventy automatically merges data from three scopes: global (project‑wide), directory (folder‑specific), and template (per‑file). By placing shared values in _data folders, you eliminate duplication and keep your content files clean.
1. Global Data – _data at the Project Root
Anything in _data at the root of your Eleventy project becomes available to every template. A common pattern is a site.json file that holds branding and navigation data.
// _data/site.json
{
"siteTitle": "Eleventy Demo",
"nav": [
{ "label": "Home", "url": "/" },
{ "label": "Blog", "url": "/blog/" }
]
}
In any template you can now access {{ siteTitle }} or iterate over {{ nav }} without repeating the values in each Markdown file.
2. Directory‑Scoped Data – _data.json Inside Folders
If a section of your site needs additional or overriding data, drop a _data.json file into that folder. For example, a blog directory might have a default author or a different layout.
// blog/_data.json
{
"author": "Ada Lovelace",
"layout": "blog-post"
}
Eleventy merges this with the global data: the author key is added, and layout overrides any global layout for files inside blog. The merge is shallow—nested objects are replaced, not deep‑merged.
3. Template‑Specific Data – Front‑Matter in Markdown
Individual Markdown files can still declare front‑matter for page‑specific values. These values win over directory or global data when keys collide.
---
title: "My First Post"
---
# Hello World
In this example, title is only defined in the file, so the global and directory scopes are ignored for that key.
4. Worked Example – From Source to HTML
Let’s walk through a minimal project structure:
.
├─ _data/site.json
├─ blog/_data.json
├─ blog/post-1.md
└─ _includes/layouts/blog-post.njk
Contents of blog/post-1.md:
---
title: "First Post"
---
# Welcome
This is my first post.
And a simple Nunjucks layout (_includes/layouts/blog-post.njk):
{{ title }} | {{ site.siteTitle }}
{% for item in site.nav %}
{{ item.label }}
{% endfor %}
{{ content | safe }}
Author: {{ author }}
Run Eleventy with a live server:
npx @11ty/eleventy --serve
Open http://localhost:8080/blog/post-1.html. The rendered page will contain the site title from site.json, the author from blog/_data.json, and the page title from the front‑matter. If you change the author in blog/_data.json and rebuild, the new value appears automatically—no touch to post-1.md required.
5. Trade‑off & Limitation – Build‑Time Only and Shallow Merge
- Build‑time only: Changing any data file forces a full Eleventy rebuild. For very large sites, this can be noticeable.
- Shallow merge: Nested objects are replaced, not recursively merged. If you need deep merging, you must handle it manually (e.g., by writing a JavaScript data file that returns a merged object).
- Version sensitivity: The
_datafolder name and cascade behavior are stable since Eleventy 0.11, but always verifyeleventy.versionin apackage.jsonif you upgrade.
6. Actionable Closing – Get Started Right Away
- Move any repeated front‑matter keys into
_data/site.json(or a_data.jsfile for computed values). - Add folder‑level
_data.jsonfiles for sections that need defaults (e.g.,blog/_data.jsonfor author or layout). - Run
npx @11ty/eleventy --serveto see changes instantly. - When you need to update a global value, edit the relevant
_datafile and rebuild. - For nested data that should merge, consider writing a
.jsdata file that returns a merged object usingObject.assignor a deep‑merge library.
By centralizing shared data, you reduce duplication, lower the chance of drift, and keep your Markdown files focused on content rather than configuration.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.