Eleventy pagination with Vento
I recently switched my Eleventy site from Nunjucks to Vento for templating. Mostly I just wanted to try it out, but I find I do prefer the {{ }} syntax over {% %}, and the ability to run vanilla JavaScript inside tags is nice.
I won't rehash Chris Kirk Nielsen's thorough post on migrating to Vento, which came in very handy. But I'll share what I learned the hard way about Eleventy pagination in Vento.
Eleventy documents a good example of how to handle pagination with Nunjucks. Following that example, my original pagination component looked like this:
{% if (pagination.pages.length > 1) %}
<nav class="pagination">
<span>Page: </span>
{% for pageEntry in pagination.pages %}
{% if page.url == pagination.hrefs[ loop.index0 ] %}
<span class="pg" aria-current="page">{{ loop.index }}</span>
{% else %}
<a href="{{ pagination.hrefs[ loop.index0 ] }}">{{ loop.index }}</a>
{% endif %}
{% endfor %}
</nav>
{% endif %}Migrating this component was the one place where I ran into real trouble, and the reason is that the documented method relies on “special variables” that are peculiar to Nunjucks. That magic loop.index0 value — which represents the current zero-indexed iteration of the for loop — is a nifty shortcut, but it doesn’t exist outside Nunjucks. You can easily swap the syntax but, of course, those special variables no longer mean anything.
After some blundering around, I figured out that Vento can in fact give you the index of a for loop (although the docs don’t exactly articulate it that way). I suspect others might run into similar issues and find this useful.
Here's the equivalent Vento pagination component that I eventually landed on:
{{ if (pagination.pages.length > 1) }}
<nav class="pagination">
<span>Page: </span>
{{# `pagination.pages` is an array of arrays, so `index` here acts as a counter #}}
{{ for index, _content of pagination.pages }}
{{if pagination.hrefs[index] == page.url}}
<span class="pg" aria-current="page">{{index + 1}}</span>
{{else}}
<a href="{{pagination.hrefs[index]}}">{{index + 1}}</a>
{{/if}}
{{/for}}
</nav>
{{ /if }}Note that _content isn't used at all, but if you don't declare it, the array isn't destructured and everything breaks.