Eleventy Static Site Generator: Audit One Page per Data Record

Your data contains three records, and the build folder contains three pages. That sounds right until two records share an ID, one page contains another record's label, or a removed record's old file is still present.

For this Eleventy static site generator task, define the mapping before building: one validated record, one stable ID route, and matching content. Check cardinality, routes, and page contents together in a fresh isolated output location.

Eleventy • record-to-route workbench — Map one JSON array through one native template into exactly one output per record, preserving stable IDs and auditing…
Eleventy • record-to-route workbench — Map one JSON array through one native template into exactly one output per record, preserving stable IDs and auditing…
Open the full example ↗

This original packet uses three fictional tool-note records and one Nunjucks template specification. It references Eleventy 3.1.6 as a chosen version; the installed version and configuration remain unknown. No native source files, generator build, server, or deployment has been created.

Make the ID the output identity

The authored data specification for _data/tools.json is:

[
  {"id": "note-a", "label": "Note A"},
  {"id": "note-b", "label": "Note B"},
  {"id": "note-c", "label": "Note C"}
]

These are fictional records, not descriptions of actual tools or a fetched inventory. Labels are ordinary text. IDs determine the route; array positions do not.

For this bounded packet, require a nonempty string ID matching lowercase letters, digits, and hyphens only, and require exact ID uniqueness. A proposed author-owned prebuild gate would enforce that contract before invoking the generator.

Missing IDs, note-a repeated twice, ../note-a, and an ID containing a slash fail the gate. Do not repair them by guessing a suffix, using the record number, or silently choosing one record. Record the issue and leave that case unbuilt.

The gate is a requirement to implement later. It is not a claim that Eleventy has already validated this dataset or that every accepted ID is safe in every deployment.

Prepare one template for the dataset

Eleventy's official pages-from-data guide documents pagination data, size 1, an alias, and a record-based permalink to create one output per item. Our records and output contract are original. Eleventy's pages-from-data guide.

Use this tool-pages.njk specification:

---
pagination:
  data: tools
  size: 1
  alias: tool
permalink: "tools/{{ tool.id }}/index.html"
---
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>{{ tool.label | escape }}</title>
</head>
<body>
  <h1>{{ tool.label | escape }}</h1>
  <p>Record ID: {{ tool.id | escape }}</p>
</body>
</html>

This is source material inside the manuscript, not a template file or built page. Under the intended configuration, tools refers to the global data array, the alias tool identifies the current record, and its validated ID supplies the output segment.

The body displays the record's label and ID using explicit text escaping. Nunjucks documents its escape filter for HTML text. Confirm the actual template environment and output during native testing; do not assume an unreviewed configuration has the desired behavior. Nunjucks's escape filter.

Keep ordinary input text unescaped until rendering. Do not pre-encode labels or mark arbitrary label text as safe markup. The permalink relies on the separate bounded ID gate; escaping an HTML body is not path validation.

Write the expected manifest first

Record ID Expected output path relative to case output root Expected visible content
note-a tools/note-a/index.html Note A; Record ID: note-a
note-b tools/note-b/index.html Note B; Record ID: note-b
note-c tools/note-c/index.html Note C; Record ID: note-c

The baseline expectation is exactly three fixture pages. Count only the outputs associated with this template and dataset, not unrelated assets or pages in a larger project.

Each route needs its own content check. A folder with three files can still fail if note-a's page says Note B. Conversely, correct individual content does not prove all expected records were emitted.

Keep the expected manifest beside a blank actual manifest:

Actual output path Matched record ID Observed label / ID Source/configuration revision Acceptance observation

The empty row is intentional. No build output has been observed.

Reorder records without changing their identity

For the reordered case, supply note-c, note-a, note-b in that order, with their original labels. The expected set of three ID paths and record-content matches remains the same.

This tests whether the route depends on stable data identity instead of a page number. It does not promise identical file enumeration order, layout, build timing, or overall performance.

If a label changes but the ID remains, the route expectation remains attached to that ID and the content expectation changes. If an ID changes, define a new route expectation and review the removed old route in a fresh case output. Do not carry a previous acceptance mark across changed data.

Test empty and removed-record cases in fresh outputs

Eleventy's pagination documentation states that an empty dataset generates no pagination pages by default; an option can instead request an empty-results page. This packet does not enable that option. Eleventy's empty-dataset behavior.

For E0, supply an empty tools array and a new, empty isolated output directory. Expect zero fixture pages.

For E1, supply only note-a and note-c and another new, empty isolated output directory. Expect two fixture pages, with no tools/note-b/index.html.

A reused folder can contain an old note-b file without proving that the current dataset generated it. This packet requires fresh case outputs so evidence has clear provenance. It does not instruct you to delete a production directory or assume automatic cleanup behavior.

Keep every case's input and output separate. Mark the old three-record manifest as historical, not as evidence for the empty or two-record case.

Hold collisions before the native build

A duplicate ID creates duplicate intended paths in this mapping. The author-owned gate should detect that before building. Do not guess whether the generator would overwrite, error, or otherwise resolve the conflict in an untested version.

The gate should also require an array of record objects with string IDs and ordinary-text string labels. Missing label data is an authoring issue, not permission to fabricate a heading.

The source contract is intentionally small. It has no remote fetch, CMS, runtime API, real-tool lookup, or user-supplied template execution. Adding one of those inputs would require a different evidence and configuration review.

Plan the native build evidence

The later implementation needs the confirmed Eleventy version, input/output configuration, data-file/template hashes, Nunjucks escaping contract, prebuild validation result, native build output, and actual manifest.

Use these expected cases:

Case Dataset or issue Expected disposition Actual observation
B0 Three original records Three exact routes and matching bodies
B1 Reordered records Same route/content set
B2 Duplicate note-a Gate rejects; no case build
B3 Missing or unsafe ID Gate rejects; no guessed route
E0 Empty array, fresh output Zero fixture pages
E1 note-a and note-c, fresh output Two pages; note-b absent

Then inspect the produced reading pages at the actual production article width and a narrow container. Keyboard-readable content, titles, text escaping, routes, and actual output files remain to be checked. No test has been reported as passed.

Copy this prompt for the fan-out packet

Create one complete, self-contained US-English HTML companion for “Eleventy • record-to-route workbench”. Return the full HTML document, with inline CSS and any JavaScript needed for the local interactions. Use the original scenario, named records, numbers and expected cases below.

Design the page for this task: use clearly labeled input or source records, a readable result or worked example, and an adjacent explanation of the evidence. Use a restrained visual hierarchy, left-aligned text, readable tables or stacked records, and a responsive layout at 720px and 360px. Provide meaningful labeled controls for Validate & project; Reverse order; Original data; Compare observations; Select text. Use keyboard-accessible native controls and visible focus. Keep the complete content readable without an external dependency.

The following brief supplies the substantive content and constraints. Native-format requests describe the material to represent or copy manually; this HTML must not pretend to create DOCX, XLSX, PDF, PPTX, H5P or another native file, run Python/Flask/Django/Snowflake/Power BI, connect a live service, send messages, or perform an authorized real-world action. Where the task requires a native source, actual observation or separate approval, retain that requirement and leave unsupplied evidence blank.

Prepare an original English Eleventy authoring packet. Do not create native files, install/run a generator, start a server,
fetch data, delete directories, deploy, capture screens, or publish. Use Eleventy 3.1.6 as the chosen reference, not installed-version proof.

Data specification _data/tools.json:
[{"id":"note-a","label":"Note A"},
 {"id":"note-b","label":"Note B"},
 {"id":"note-c","label":"Note C"}]
Fictional records only; labels ordinary text.

One tool-pages.njk specification:
pagination.data tools; size 1; alias tool.
permalink "tools/{{ tool.id }}/index.html". Body displays current tool.id and tool.label with explicit escape filter. Nunjucks environment/output escaping must be confirmed in native tests. No pre-encoded input labels or arbitrary safe markup.

Original author-owned prebuild gate, not an implemented feature:
Dataset is an array of records with string ID and label. ID nonempty; lowercase letters, digits and hyphens only. IDs unique exactly. Reject duplicate/missing/unsafe IDs before build. No silent suffix, array-position identity, inferred route or guessed
generator overwrite/collision behavior.

Expected baseline manifest:
tools/note-a/index.html -> Note A and note-a.
tools/note-b/index.html -> Note B and note-b.
tools/note-c/index.html -> Note C and note-c. Exactly three fixture outputs; do not count unrelated assets/pages.

Cases:
Reorder note-c/note-a/note-b -> same route/content set. Duplicate note-a -> gate hold, no case build. Missing ID, ../note-a or slash-containing ID -> gate hold. Empty [] in a new empty isolated case output -> zero fixture pages. Remove note-b, use another new empty output -> two pages, note-b absent. Do not enable generatePageOnEmptyData or reuse stale output as proof. No recursive deletion or production-directory operation.

Deliver data/template specifications inside the manuscript, validation
contract, expected manifest, blank actual manifest and case matrix. Record source hashes, config, installed generator/Nunjucks versions,
gate result, actual build output and observed route/content matches later. Changed data/template/config requires fresh acceptance; native historical
evidence remains labeled with its original case.

No performance, live link, CMS, runtime API or deployment claim. Actual build, escaping, visual references, article-width and narrow
layout checks remain pending.  Native sources/build manifest remain authoritative;
NOS does not execute Eleventy or verify routing.

COMPLETE AUTHORED SCENARIO AND EXPECTED CASES
The following is the supplied reading/teaching/calculation record to represent in the companion. Preserve its particular content, examples, source references and unknowns. Wording about a future native implementation refers to that native task, not permission to omit this HTML companion.

# Eleventy Static Site Generator: Audit One Page per Data Record

Your data contains three records, and the build folder contains three pages. That sounds right until two records share an ID, one page contains another record's label, or a removed record's old file is still present.

For this Eleventy static site generator task, define the mapping before building: one validated record, one stable ID route, and matching content. Check cardinality, routes, and page contents together in a fresh isolated output location.

This original packet uses three fictional tool-note records and one Nunjucks template specification. It references Eleventy 3.1.6 as a chosen version; the installed version and configuration remain unknown. No native source files, generator build, server, or deployment has been created.

## Make the ID the output identity

The authored data specification for **_data/tools.json** is:

    [
      {"id": "note-a", "label": "Note A"},
      {"id": "note-b", "label": "Note B"},
      {"id": "note-c", "label": "Note C"}
    ]

These are fictional records, not descriptions of actual tools or a fetched inventory. Labels are ordinary text. IDs determine the route; array positions do not.

For this bounded packet, require a nonempty string ID matching lowercase letters, digits, and hyphens only, and require exact ID uniqueness. A proposed author-owned prebuild gate would enforce that contract before invoking the generator.

Missing IDs, note-a repeated twice, ../note-a, and an ID containing a slash fail the gate. Do not repair them by guessing a suffix, using the record number, or silently choosing one record. Record the issue and leave that case unbuilt.

The gate is a requirement to implement later. It is not a claim that Eleventy has already validated this dataset or that every accepted ID is safe in every deployment.

## Prepare one template for the dataset

Eleventy's official pages-from-data guide documents pagination data, size 1, an alias, and a record-based permalink to create one output per item. Our records and output contract are original. [Eleventy's pages-from-data guide](https://www.11ty.dev/docs/pages-from-data/).

Use this **tool-pages.njk** specification:

    ---
    pagination:
      data: tools
      size: 1
      alias: tool
    permalink: "tools/{{ tool.id }}/index.html"
    ---
    <!doctype html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>{{ tool.label | escape }}</title>
    </head>
    <body>
      <h1>{{ tool.label | escape }}</h1>
      <p>Record ID: {{ tool.id | escape }}</p>
    </body>
    </html>

This is source material inside the manuscript, not a template file or built page. Under the intended configuration, tools refers to the global data array, the alias tool identifies the current record, and its validated ID supplies the output segment.

The body displays the record's label and ID using explicit text escaping. Nunjucks documents its escape filter for HTML text. Confirm the actual template environment and output during native testing; do not assume an unreviewed configuration has the desired behavior. [Nunjucks's escape filter](https://mozilla.github.io/nunjucks/templating.html#escape).

Keep ordinary input text unescaped until rendering. Do not pre-encode labels or mark arbitrary label text as safe markup. The permalink relies on the separate bounded ID gate; escaping an HTML body is not path validation.

## Write the expected manifest first

| Record ID | Expected output path relative to case output root | Expected visible content |
| --- | --- | --- |
| note-a | tools/note-a/index.html | Note A; Record ID: note-a |
| note-b | tools/note-b/index.html | Note B; Record ID: note-b |
| note-c | tools/note-c/index.html | Note C; Record ID: note-c |

The baseline expectation is exactly three fixture pages. Count only the outputs associated with this template and dataset, not unrelated assets or pages in a larger project.

Each route needs its own content check. A folder with three files can still fail if note-a's page says Note B. Conversely, correct individual content does not prove all expected records were emitted.

Keep the expected manifest beside a blank actual manifest:

| Actual output path | Matched record ID | Observed label / ID | Source/configuration revision | Acceptance observation |
| --- | --- | --- | --- | --- |
| | | | | |

The empty row is intentional. No build output has been observed.

## Reorder records without changing their identity

For the reordered case, supply note-c, note-a, note-b in that order, with their original labels. The expected set of three ID paths and record-content matches remains the same.

This tests whether the route depends on stable data identity instead of a page number. It does not promise identical file enumeration order, layout, build timing, or overall performance.

If a label changes but the ID remains, the route expectation remains attached to that ID and the content expectation changes. If an ID changes, define a new route expectation and review the removed old route in a fresh case output. Do not carry a previous acceptance mark across changed data.

## Test empty and removed-record cases in fresh outputs

Eleventy's pagination documentation states that an empty dataset generates no pagination pages by default; an option can instead request an empty-results page. This packet does not enable that option. [Eleventy's empty-dataset behavior](https://www.11ty.dev/docs/pagination/).

For E0, supply an empty tools array and a new, empty isolated output directory. Expect zero fixture pages.

For E1, supply only note-a and note-c and another new, empty isolated output directory. Expect two fixture pages, with no tools/note-b/index.html.

A reused folder can contain an old note-b file without proving that the current dataset generated it. This packet requires fresh case outputs so evidence has clear provenance. It does not instruct you to delete a production directory or assume automatic cleanup behavior.

Keep every case's input and output separate. Mark the old three-record manifest as historical, not as evidence for the empty or two-record case.

## Hold collisions before the native build

A duplicate ID creates duplicate intended paths in this mapping. The author-owned gate should detect that before building. Do not guess whether the generator would overwrite, error, or otherwise resolve the conflict in an untested version.

The gate should also require an array of record objects with string IDs and ordinary-text string labels. Missing label data is an authoring issue, not permission to fabricate a heading.

The source contract is intentionally small. It has no remote fetch, CMS, runtime API, real-tool lookup, or user-supplied template execution. Adding one of those inputs would require a different evidence and configuration review.

## Plan the native build evidence

The later implementation needs the confirmed Eleventy version, input/output configuration, data-file/template hashes, Nunjucks escaping contract, prebuild validation result, native build output, and actual manifest.

Use these expected cases:

| Case | Dataset or issue | Expected disposition | Actual observation |
| --- | --- | --- | --- |
| B0 | Three original records | Three exact routes and matching bodies | |
| B1 | Reordered records | Same route/content set | |
| B2 | Duplicate note-a | Gate rejects; no case build | |
| B3 | Missing or unsafe ID | Gate rejects; no guessed route | |
| E0 | Empty array, fresh output | Zero fixture pages | |
| E1 | note-a and note-c, fresh output | Two pages; note-b absent | |

Then inspect the produced reading pages at the actual production article width and a narrow container. Keyboard-readable content, titles, text escaping, routes, and actual output files remain to be checked. No test has been reported as passed.



Implement the local companion rather than returning a text-only plan. Preserve every numerical fixture and the distinction between illustrative expectations and actual evidence. Any native-runtime or classroom tests mentioned above remain tests to perform in the proper environment; do not mark them passed. Keep edits and practice responses in this open page only, without claiming persistent storage. Provide invalid/missing-input feedback and reset behavior that agree with this specific brief. Do not claim accessibility certification, learning gains, real approvals or test results that were not observed.

Review the prepared build-review copy

After native testing, a reading copy can place the expected record mapping beside the actual manifest, showing whether each ID produced exactly one matching fixture page.

Keep native data, template, configuration, validation result, and build evidence authoritative. A rendered review page does not run Eleventy, establish routes, or remove stale files.

Explore NOS

Give the reviewer three things to compare: the record, its exact output path, and the content observed in that output.

Keep reading