Beginner

Tags

Auto-generated tag pages built from a custom collection — every demo tag gets its own page with zero manual wiring.

1 min read

Live Implementation

Every tag below is generated from the demoTags collection — add a new tag to any demo's front matter and a page for it appears here automatically:

How It Works

Every demo’s front matter has a tags array, like ["css", "javascript"]. A directory data file (src/demos/demos.json) also stamps a structural "demo" tag onto every file in that folder, and Eleventy merges those two arrays together, so a demo’s final tag list ends up as ["demo", ...whatever you wrote].

A custom collection called demoTags walks every demo, pulls out the non-structural tags into a Set (which dedupes and sorts them for free), and hands back the list. One paginated template, tags.njk, then asks Eleventy to spit out one page per tag, landing at /demos/tags/<tag>/.

Folder Structure

src/_11ty/collections/demoTags.js ← builds the unique tag list
src/tags.njk                       ← paginated template, one output per tag
src/_includes/components/tag-list.njk

Important Files

src/_11ty/collections/demoTags.js

export default function demoTags(collectionApi) {
    const items = collectionApi.getFilteredByGlob("src/demos/*.md");
    const tagSet = new Set();
    items.forEach((demo) => {
        (demo.data.tags || []).forEach((tag) => {
            if (tag !== "demo") tagSet.add(tag);
        });
    });
    return [...tagSet].sort();
}

src/tags.njk

---
pagination:
  data: collections.demoTags
  size: 1
  alias: tag
permalink: "/demos/tags/{{ tag | slugify }}/"
eleventyExcludeFromCollections: true
eleventyComputed:
  title: "{{ tag }}"
  description: "Every demo tagged “{{ tag }}”."
---
{% extends "layouts/base.njk" %}
{% import "components/demo-card.njk" as demoCardC %}

{% set matching = collections.demos | byTag(tag) %}

{% block content %}
<div class="wrapper">
  <header class="page__header">
    <p class="page__eyebrow"><a href="/demos/">← All demos</a></p>
    <h1 class="page__title">Tag: {{ tag }}</h1>
    <p class="page__lede">{{ matching.length | pluralize("demo") }} tagged “{{ tag }}”.</p>
  </header>

  <div class="demo-grid">
    {% for demo in matching %}
      {{ demoCardC.demoCard(demo) }}
    {% endfor %}
  </div>
</div>
{% endblock %}

Notes

  • Add a brand-new tag to any demo’s front matter and its page just appears on the next build. Nothing else to touch.
  • Tag pages reuse the same demoCard macro as the main /demos/ listing, so they look consistent without any extra work.