HAP at his laptop building his first Eleventy site

HAP's Learning Lab: Eleventy Fundamentals

Zero-Config Magic That Actually Works

Welcome to Station 3! I installed Eleventy, added a 7-line index.md with front matter and a special Nunjucks template, _includes/base.njk, from a tutorial I found. Then at the terminal I ran npx @11ty/eleventy. The terminal said it built my site in 0.02 seconds.

I thought it was broken. Nothing that fast could actually work!

But when I opened the browser... there was my site. A real HTML page, generated from my Markdown file. No configuration file. No complex setup. Just... done.

"That's the zero-config philosophy," Prof. Teeters explained. "Eleventy has sensible defaults. You only need to configure what you want to change. Most of the time, it just figures out what you meant."

I stared at the screen for a moment, processing what just happened. I'd spent two days trying to set up Gatsby. Eleventy took two SECONDS.

Let me show you how this magic works, because once you understand it, everything clicks into place... 🟠

What You'll Learn at This Station

HAP's Discovery: Eleventy has a few core concepts that unlock everything else. Once I understood these, building my blog went from confusing to fun. Prof. Teeters calls them "the building blocks." Here are the three that made the biggest difference for me:

📝 Templates Are Flexible

Eleventy supports multiple template languages! I use Markdown (.md) for content and Nunjucks (.njk) for layouts. You can mix and match based on what each page needs. Start with what you know!

📚 Collections Are Automatic

Put Markdown files in a folder and add a tag to the front matter, and Eleventy automatically creates a "collection" you can loop through. My blog posts appeared in a list without me writing any special code!

🌊 The Data Cascade

Data flows from global files → directory files → front matter in each page. Each level can override the previous. This is how I set site-wide defaults but customize individual posts!

HAP surrounded by tangled code with an 'oops' expression

HAP's Confession:

  • I copied someone's 50-line config file I found online, not knowing what it was meant to do. Sure enough, it did funny things to my little site. Prof. Teeters gently asked, "What problem are you solving?" I didn't have an answer.
  • I thought .njk was a typo the first time I saw it. Turns out it stands for Nunjucks, a template language I can use for my HTML. Grace Hopper—who of course knew all about template languages—gave me a quick primer. 😳
  • I kept forgetting the triple dashes around front matter and putting quotes around the strings wrong. Let me tell you, writing just title: My Post: Part One at the top of a file doesn't work. I had to learn the simple rules for front matter and then all was good with my Markdown files.
  • I put blog posts directly in the root folder instead of organizing them in content/blog/. My project got messy fast. Prof. Teeters showed me how folder structure not only keeps everything manageable but also acts like my database.
  • I restarted the dev server after every tiny Markdown change before learning it hot-reloads content automatically. Config changes need a restart, but content updates appear instantly! Knowing that, I keep my browser open and check the site as I develop. As Prof. Teeters says, "Fixing mistakes early will save you time, HAP!"

Where Everything Lives

Since I wanted a multi-page site, and before I could customize anything, I needed to understand where everything lives. Prof. Teeters walked me through the folder structure, and suddenly the project made sense. Here's how an Eleventy project is organized:

Eleventy Project Structure:
my-blog/
├── _data/                  # Global data files
│   └── metadata.js         # Site title, author, URL
├── _includes/              # Reusable templates
│   └── layouts/
│       ├── base.njk        # Main HTML wrapper
│       └── post.njk        # Blog post template
├── content/                # Your actual content
│   └── blog/
│       ├── first-post.md   # A blog post
│       └── second-post.md  # Another blog post
├── css/                    # Stylesheets
├── public/                 # Static files (copied as-is)
├── eleventy.config.js      # Configuration (optional!)
└── _site/                  # Generated output (don't edit!)

📁 _data/

Global data that every page can access. I put my site title and author info here.

📁 _includes/

Templates and layouts. The underscore means Eleventy won't turn these into pages.

📁 content/

Where my actual content lives. Blog posts, about page, anything I want to publish.

📁 _site/

The output folder. Eleventy generates this—never edit files here! They get overwritten on every build.

HAP having a mind-blowing realization about how Eleventy concepts connect

HAP's Breakthrough:

I made the mistake of editing files in _site/ thinking that was my real project. I lost my changes three times. I was really frustrated before Prof. Teeters noticed and explained that Eleventy regenerates that entire folder on every build. Always edit source files, never output files!

The Three Building Blocks

Three concepts make Eleventy tick: front matter, layouts, and collections. Once I understood how they work together, building pages became almost automatic.

📋 Front Matter

Front matter is data at the top of each file, wrapped in triple dashes. It tells Eleventy how to handle the file:

Example front matter:
---
title: "My First Blog Post: Part One!"
date: 2025-11-23
layout: layouts/post.njk
tags:
  - posts
---

This is my content! Everything below the second `---` is the actual page content.

And its **Super Power**? It uses Markdown syntax that I already **KNOW** and **LOVE**.

The title shows up in the browser tab. The date helps sort posts. The layout tells Eleventy which template to wrap this content in. And tags: posts adds this page to the "posts" collection automatically!

🎨 Layouts

Layouts are templates that wrap your content. They're like cookie cutters—same shape for every cookie, different content inside.

Simplified post.njk layout:
---
layout: layouts/base.njk
---
<article>
  <h1>{{ title }}</h1>
  <time>{{ date }}</time>
  {{ content | safe }}
</article>

See how {{ title }} pulls from the front matter? And {{ content | safe }} is where my Markdown content appears after Eleventy converts it to HTML. The | safe part tells Nunjucks "trust this HTML, don't escape it."

📚 Collections

Collections group related content. If I tag posts with tags: posts, Eleventy automatically creates a collection called collections.posts that I can loop through.

Showing posts on home page:
<ul>
{% for post in collections.posts %}
  <li>
    <a href="{{ post.url }}">{{ post.data.title }}</a>
  </li>
{% endfor %}
</ul>

This loops through every post and creates a link. I didn't have to configure anything or type a lot of HTML—just adding tags: posts to each blog post's front matter was enough. Eleventy figured out the rest. And the best part? Once I have the template, I can add or delete posts and the HTML automatically gets written with the right number of <li> tags. Easy-Peasy!

The Data Cascade: How Data Flows

HAP looking confused while studying the data cascade

HAP's Initial Confusion:

The data cascade confused me at first. Prof. Teeters drew a diagram, and everything clicked. Data flows DOWN from general to specific, and more specific data wins:

Level 1: Global Data

_data/metadata.js

Site-wide defaults like author name, site title, URL

↓ flows down to...

Level 2: Directory Data

content/blog/blog.json

Folder-specific settings like default layout for all posts

↓ flows down to...

Level 3: Front Matter

each individual .md file

Page-specific overrides like guest author or custom layout

More specific = higher priority!

Data cascade in action:
In _data/metadata.js:
  author: "HAP"

In content/blog/blog.json:
  layout: "layouts/post.njk"

In content/blog/guest-post.md front matter:
  author: "Grace Hopper"

🟠 Result:

  • For guest-post.md, the author is "Grace Hopper" (front matter wins!)
  • For other posts, I am the author "HAP" (from global data)
  • All blog posts use the post.njk layout (from directory data)
HAP celebrating after understanding the data cascade

HAP's Aha Moment:

Prof. Teeters explained it this way: "Think of it like the CSS cascade. In CSS, you set some default values at the top level, and as more CSS loads from deeper files or more specific rules, those values can be overwritten." Eleventy's data cascade works the same way—the more specific data wins. That analogy made it click for me!

🎓 Eleventy Fundamentals Quick Reference

1

Front Matter

Data at top of file wrapped in ---. Example: title: "My Post"

2

Layout

Template that wraps content. Example: layout: layouts/post.njk

3

Collection

Group of related pages created by tags. Example: tags: posts

4

Data Cascade

How data flows and merges: Global → Directory → File (most specific wins!)

5

{{ }} Syntax

Output a value in Nunjucks templates. Example: {{ title }}

6

{% %} Syntax

Logic like loops and conditions. Example: {% for post in posts %}