Beginner

Data Files

Eleventy's global _data files, explained using this site's own real data files as the example.

2 min read

Live Implementation

Every value below comes straight from src/_data/site.js — the same file that sets this page's browser tab title, the footer copyright, and every other page on this site:

site.title
11ty Demos
site.author.name
Vinay Ranjan
site.author.url
https://vranjan.dev/
site.year
2026

The whole object, dumped as real JSON with the toJson filter — the same object, no separate copy to keep in sync:

{
  "title": "11ty Demos",
  "shortTitle": "11ty Demos",
  "description": "I kept rebuilding the same Eleventy features on every project, so I put them all in one place. Every demo here actually works, not just written about.",
  "url": "https://11ty-demos.netlify.app",
  "author": {
    "name": "Vinay Ranjan",
    "url": "https://vranjan.dev/"
  },
  "year": 2026
}

How It Works

Any file dropped into src/_data/ becomes available in every template on the site, under a key that matches the filename. site.js exports a plain object, so site.title, site.author, and site.year are just there — no registration, no import, nothing to wire up:

export default {
    title: "11ty Demos",
    author: { name: "Vinay Ranjan", url: "https://vranjan.dev/" },
    year: new Date().getFullYear(),
};

That’s the whole file. This site has been using it since the very first page — it’s what sets the <title> tag, the footer copyright year, and the author link, on every single page.

A data file doesn’t have to be a static object, either — it can export an async function instead, and Eleventy will await it once per build and cache the result. Half the “live” demos on this site are actually just data files doing real async work at build time: lighthouse.js reads a committed JSON file, and imageGalleryDemo.js fetches real photos from an API and processes them with @11ty/eleventy-img. Same mechanism, same filename-to-key rule, just returning a promise instead of an object.

Folder Structure

src/_data/site.js                 ← the plain-object example on this page
src/_data/lighthouse.js           ← async example: reads a JSON file
src/_data/imageGalleryDemo.js     ← async example: fetches + processes images
src/_includes/demo-live/data-files.njk ← this page's live values

Important Files

src/_data/site.js

export default {
    title: "11ty Demos",
    shortTitle: "11ty Demos",
    description:
        "I kept rebuilding the same Eleventy features on every project, so I put them all in one place. Every demo here actually works, not just written about.",
    url: "https://11ty-demos.netlify.app",
    author: {
        name: "Vinay Ranjan",
        url: "https://vranjan.dev/",
    },
    year: new Date().getFullYear(),
};

The whole site object is also dumped as real JSON below, using a small toJson filter (JSON.stringify(value, null, 2) in one line) — see Custom Filters for more on how filters like that get registered.

Notes

  • The filename is the only thing that decides the data’s key — site.js becomes site, lighthouse.js becomes lighthouse. Rename the file and every template referencing the old name breaks, on purpose — there’s no separate registration step to forget to update.
  • Data files merge the same way front matter does: a file closer to the template (directory data, then front matter) can override a value from a more global one. src/_data/ sits at the very top of that cascade, which is why it’s the right place for things every page needs, like site.title.