Diagnosing Eleventy Pagination: Fixing Missing Pages and Repeated Content
Fix common Eleventy pagination errors including overwritten pages, repeated content, and incorrect page counts with this diagnostic guide.
03 Sept 2025, 10:45 UTC

The Symptom: Pagination Mismatch
You have configured a template to paginate a large data set or collection, but the output in your _site folder doesn't match your expectations. Common failure states include only one page being generated despite having hundreds of items, every page displaying the exact same first few items, or the total page count being mathematically incorrect.
Diagnostic Matrix
Use this table to map your specific symptom to the most likely configuration error.
| Symptom | Likely Cause | Primary Check |
|---|---|---|
Only one page exists in _site |
Static permalink | Check if permalink includes pagination.pageNumber |
| Every page shows the same items | Iterating wrong array | Check if loop uses pagination.items vs the raw collection |
| Incorrect number of pages | Data source length | Verify the length of the data key referenced in pagination.data |
| Content doesn't update on build | Build cache/Incremental | Check if --incremental is active or remote data is cached |
Step-by-Step Resolution Path
1. Verify the Data Source
Before checking the template, confirm that Eleventy sees the data you think it does. If the data source is empty or shorter than expected, the pagination logic will fail silently.
- Run the build with the debug flag:
DEBUG=Eleventy* npx @11ty/eleventy. - Inspect the logs for warnings regarding unresolvable pagination data.
- If using a global data file (e.g.,
_data/members.json), ensure the filename matches the key used in your front matter.
2. Fix Overwritten Output (The Permalink Issue)
A common mistake is defining a static permalink. If your permalink is /blog/archive/index.html, Eleventy will generate 10 pages but write them all to the same file, effectively overwriting the previous page until only the last one remains.
Correct Configuration:
---
pagination:
data: collections.posts
size: 10
alias: posts
permalink: "/blog/page/{{ pagination.pageNumber }}/index.html"
---
Risk: Changing the permalink on a live site will change your URLs and break existing SEO links. You must implement 301 redirects if you modify this on a production site.
3. Correct the Loop Variable
If your pages are generated but the content is identical on every page, you are likely iterating over the global collection instead of the paginated subset.
Wrong: Iterating collections.posts inside the template. This renders the entire list on every single page.
Right: Iterating the alias defined in your pagination block (or pagination.items if no alias is provided).
{# If alias is 'posts' #}
{% for post in posts %}
<h2>{{ post.data.title }}</h2>
{% endfor %}
4. Handle the First Page URL
Using /page/{{ pagination.pageNumber }} results in /page/1 for the first page. Most users prefer the root directory for the first page. Use a conditional in your template or a computed permalink to handle this logic.
Verification and Testing
To verify the fix, create a minimal reproduction case:
- Create a dummy data file with exactly 25 items.
- Set
pagination.sizeto 10. - Run the build and check the
_sitedirectory. - Success Criteria: Exactly 3 output files must exist, and the items in page 1 must not appear on page 2.
When to Escalate
If the above steps do not resolve the issue, the problem likely exists outside the basic pagination config. Escalate to a full system audit if:
- You are using
eleventyComputedto dynamically set pagination values, which can create circular dependencies. - You have custom plugins that transform collections after the pagination phase.
- You are mixing ESM and CommonJS modules in Eleventy 2.x/3.x, leading to inconsistent data resolution.
To isolate these, disable all plugins in .eleventy.js and test with a basic Markdown template. If the issue disappears, re-enable plugins one by one to identify the conflict.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.