When to Use Pagination in Eleventy
Eleventy’s Pagination feature often confuses new users,
because you might think you need it if you want to put more than one thing on the same page. In this
short entry, I’ll try to explain what it’s used for. Let’s assume you have a list like ["foo", "bar", "baz"]
with the name allData
. (Your real data might be a list like this, a collection
like collections.posts
, or any other list you like.)
Use pagination to create multiple pages from a single list
For example, to create pages for each item in the list, i.e. /tags/foo/, /tags/bar/, and /tags/baz/, you could create a file named tag.njk or tag.liquid (using Nunjucks or Liquid syntax, respectively):
Nunjucks---
pagination:
data: allTags
alias: item
size: 1
permalink: "/tag/{{ item }}/"
layout: someLayout.njk
---
This is the page for {{ item }}.
The filename of the template can be anything you like, since the pages created will be named using
the format in permalink
.
Don’t use pagination to put several items on the same page
Instead, use looping constructs (defined by the template
language you’re using) like Liquid or Nunjucks’s for
. For
example, you could create an HTML list from allTags
in any Liquid or Nunjucks template like
so:
Nunjucks<ul>
{%- for tag in allTags -%}
<li><a href="/tags/{{ tag }}/">{{ tag }}</a></li>
{%- endfor -%}
</ul>
A real example
The tag pages on A Place For My Head are created using pagination (with Pug as the template language):
Pug---
pagination:
data: collections.postTags
size: 1
alias: postTag
permalink: "| /tags/#{metadata.slug(postTag)}/"
dynamicPermalink: true
---
extends ../layouts/index.pug
include ../layouts/mixins/toc.pug
include ../layouts/mixins/blog-info.pug
block content
main.tag-page(aria-labelledby="title")
h1#title= postTag
p.toc-welcome Articles tagged ‘#{postTag}’.
- const posts = collections.posts.filter((p) => (p.data.postTags || []).includes(postTag));
+posts(posts)
+blog-info()
This creates a page for each tag at /tags/slug/ (where slug is
the URI-friendly version of the tag). For instance, the ‘Gaming’ tag has a page at
/tags/gaming. Then I use Pug’s each
keyword to list all known tags
on a single page in a new template:
Pug---
permalink: "/tags/"
dynamicPermalink: false
title: "All Tags"
---
extends ../layouts/index.pug
block content
main.tags-list-page(aria-labelledby="title")
h1#title= title
- const tags = [...collections.postTags].sort(postUtils.compareLowercase);
ul.tags-list
each tag of tags
li.tags-list__tag
a(href=`/tags/${metadata.slug(tag)}/`)= tag
Giving us a very plain page which nonetheless serves the purpose: