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.

Tagged: Eleventy