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 returnsfalsefrom 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
- Project structure for the project-shape conventions this pattern slots into.
- Page context reference for what Baseline reads off each page at cascade time.
Previous: Project structure
Next: Content helpers