EnglishNederlandsFrançais Toggle theme

Eleventy Baseline

Start building your site, skip the recurring setup work.
Table of Contents

Content organisation

Every page on a Baseline site has two layers behind it. One is structural: where the page lives, what layout wraps it, whether it shows up in nav. The other is the content's own metadata: title, description, date. They want different homes.

The pattern is to keep structure in a sibling *.11tydata.js file and content metadata in the page's front matter. This isn't a Baseline rule. It's a way of using Eleventy's data cascade that scales as your sections grow.

STRUCTURE (*.11tydata.js)  -> routing, grouping, layout, visibility
CONTENT   (front matter)    -> title, slug, description, date

Structure is what every page in a section shares. Content is what makes one page different from the next. Mix them and the section gets harder to reason about every time you add a page.


The structural side

Drop a sibling data file next to the section's pages. Eleventy applies its values as defaults to every page in the directory, and per-page front matter can still override anything specific.

// src/content/blog/blog.11tydata.js
export default {
	group: 'blog', // top-level URL segment
	segment: '', // optional second segment
	type: 'post', // free-form classifier for collections and templates

	order: 0, // sort key for hand-ordered lists
	nav: true, // show in nav lists
	draft: false, // overridden by individual pages when needed
	hidden: false, // exclude from indexes without dropping the page

	layout: 'layouts/post.njk' // cascades to every page in the folder

	// permalink (covered below)
};

layout is read by Eleventy. draft is read by Baseline's drafts preprocessor. The rest (group, segment, type, order, nav, hidden) are your own keys; they live in the cascade and you read them from templates or from the permalink function. Keep the ones you actually use; empty conventions rot.

The content side

Front matter stays small and per-page:

---
title: 'A short title'
slug: 'a-short-title'
description: 'One-sentence description of this specific page.'
date: 2026-05-01
---

Four fields, every page. Title and description for the head module and link previews. Slug for the URL and for wikilinks to find the page. Date for ordering and for the sitemap's lastmod.

Per-page exceptions go here too. If a single post needs a different layout, declare layout in its front matter; the cascade picks the more specific value.

The two layers meet at the permalink

The cleanest place to see the split is the permalink function. It reads slug from front matter and the structural keys from the data file, and composes the URL from both:

// src/content/blog/blog.11tydata.js
export default {
	// permalink (covered below)
	permalink: function (data) {
		const { slug, page, group, segment } = data;

		// Don't try to render the data file itself as a page.
		if (page.inputPath.includes('11tydata.js')) {
			return false;
		}

		// Front-matter slug wins; otherwise fall back to the file's own slug.
		const slugified = slug ? this.slugify(slug) : page.fileSlug;

		// Compose /<group>/<segment>/<slug>/, skipping empty parts.
		const parts = [];
		if (group) parts.push(this.slugify(group));
		if (segment) parts.push(this.slugify(segment));
		parts.push(slugified);

		// Leading slash anchors to the site root; trailing slash is the project convention.
		return '/' + parts.join('/') + '/';
	}
};

A page in src/content/blog/ with slug: 'first-post' resolves to /blog/first-post/. Add segment: '2026' in the data file and every page in the folder gets /blog/2026/<slug>/ without each post having to spell out its own path.


Worth knowing

  • Front matter overrides the data file. Eleventy resolves to the more specific value, so a single page can opt out of any default by declaring it in front matter.
  • The data file isn't a page. The inputPath.includes('11tydata.js') check returns false from the permalink so Eleventy doesn't try to render it.
  • Paths use a leading slash. Without it, the permalink resolves relative to the input subdirectory rather than the site root.

See also