DEV Community

Cover image for Add pagination for dynamic data in Eleventy
Josef Biehler
Josef Biehler

Posted on • Updated on

Add pagination for dynamic data in Eleventy

Eleventy has a nice feature for creating a pagination with ease. Continue reading if you want to break your single page with many items into many pages with only few items.

Setup

We simulate a asynchronous request that fetches many data from a server. To add a new collection in eleventy you have to provide a configuration file (.eleventy.js) and call eleventyConfig.addCollection:

// project/.eleventy.js


module.exports = function(eleventyConfig) {
  eleventyConfig.addCollection("manyData", async () =>
    new Promise(resolve => {
      const results = [];
      for(var i = 0; i < 100; i++) {
        results.push({
          id: i,
          text: `item ${i}`
        });
      }
      resolve(results);
    })
  );

  return {
    dir: {
      input: "./views"
    }
  }
}

The addCollection function accepts a function as parameter that must return an array with data. If you return a Promise eleventy will wait until it resolves.

How it works

You need a frontmatter header that defines the collection, the size of each sub collection and some other stuff.

---
pagination:
  data: collections.manyData
  size: 2
  reverse: true
---

As you can see, I am reversing the collection here. In this simple example, this is not very useful because I would be able to reverse the collection in the .eleventy.js config, too. In a subsequent blog post you will see why you might need this stuff.

To iterate over the subcollection, eleventy provides you the pagination object that contains a property named items. It can be used as any other collection.

{%- for item in pagination.items %}
    <div style="background-color: red; margin: 10px; width: 100px;">{{ item.text }}</div>
{% endfor -%}

Result:

result

Simple Navigation

The best pagination is worth nothing without a possibility to jump to the next page. Eleventy has a very good documentation about it. A very simple navigation consists of two arrows:

{% if pagination.href.previous %}
    <span><a href="{{ pagination.href.previous }}">&lt;</a></span>
{% endif %}

{% if pagination.href.next %}
    <span><a href="{{ pagination.href.next }}">&gt;</a></span>
{% endif %}

Result:

Result

Summary

Pagination done easily! You learned some basics about pagination in eleventy. Next time I show you how you can create a more sophisticated navigation bar.


Found a typo?

As I am not a native English speaker, it is very likely that you will find an error. In this case, feel free to create a pull request here: https://github.com/gabbersepp/dev.to-posts . Also please open a PR for all other kind of errors.

Do not worry about merge conflicts. I will resolve them on my own.

Discussion (7)

Collapse
bayuangora profile image
Bayu Angora • Edited on

I tried your method but always got this error. How to fix it?

error

Collapse
gabbersepp profile image
Josef Biehler Author

Can you provide your source code so I can have a look at it?

Collapse
bayuangora profile image
Bayu Angora • Edited on

Every single post is works. But I always got an error in pagination.

Please check or fork my repo here ->
github.com/BayuAngora/11ty

Thread Thread
gabbersepp profile image
Josef Biehler Author

Hi, thanks! I will try it out until tomorrow :-)

Thread Thread
bayuangora profile image
Bayu Angora

Thanks, Josef. I hope it's fixed.

Thread Thread
gabbersepp profile image
Josef Biehler Author

Sorry for the late reply. I had to fix some other problems. I made a pull request and added some comments in the message: github.com/BayuAngora/11ty/pull/1

Your mentioned problem exists because you wanted to have a permalink for /blog/index.md. But the index.md file is duplicated due to the usage of pagination. So you can't tell eleventy to use permalink /blog.html for all those duplicates. To fix this, I have included "pagination.pageNumber" in the permalink and adjusted the index.html to link to "/blog/page-0.html".

See this:
11ty.dev/docs/pagination/#remappin...

Thread Thread
bayuangora profile image
Bayu Angora

Instead of adding 0 into permalink, I rather use this ->

blog/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber | plus: 1 }}/{% endif %}index.html

And everything is fixed now. Thank you so much, Josef.