Pagination
This page shows you how to add pagination to your loops.
How it works
The Loop block can assign a query name to its query. Once named, you can reference the query results — including pagination — after the loop. For example, if you set the query name to products:
{% for product in get_posts({'post_type': 'product', 'posts_per_page': 12}) %}
<h2>{{ product.title }}</h2>
{% endfor %}
{{ products.pagination }}
If you need pagination or a total count before the loop, use a Variable block instead:
{% set products = get_posts({'post_type': 'product', 'posts_per_page': 12}) %}
<p>{{ products.found_posts }} products</p>
{{ products.pagination }}
{% for post in products %}
<h2>{{ post.title }}</h2>
{% endfor %}
Simple output
The quickest way — outputs default pagination markup:
{{ products.pagination }}
Place it before the loop, after the loop, or both.
Custom pagination
Loop over pagination.pages for full control:
<nav class="pagination">
{% if products.pagination.prev %}
<a href="{{ products.pagination.prev.link }}">Previous</a>
{% endif %}
{% for page in products.pagination.pages %}
{% if page.current %}
<span class="current">{{ page.title }}</span>
{% endif %}
{% if not page.current %}
<a href="{{ page.link }}">{{ page.title }}</a>
{% endif %}
{% endfor %}
{% if products.pagination.next %}
<a href="{{ products.pagination.next.link }}">Next</a>
{% endif %}
</nav>
Query properties
These are available on any variable that holds a query result:
| Property | Type | Description |
|---|---|---|
products.found_posts | int | Total items matching the query across all pages |
products.pagination | object | Pagination object (render directly or access sub-properties) |
products.pagination.prev | object or null | Previous page |
products.pagination.next | object or null | Next page |
products.pagination.pages | array | All page objects |
Page object
Each item in pagination.pages:
| Property | Type | Description |
|---|---|---|
page.link | string | URL to the page |
page.title | string | Page number or label |
page.current | bool | True if this is the current page |
Full example
{% set products = get_posts({'post_type': 'product', 'posts_per_page': 10}) %}
<header>
<h1>Products ({{ products.found_posts }})</h1>
{{ products.pagination }}
</header>
{% for post in products %}
<article>
<h2>{{ post.title }}</h2>
<p>{{ post.excerpt }}</p>
</article>
{% endfor %}
<footer>
{{ products.pagination }}
</footer>
Main query pagination
For archives and search results, use the posts variable to access the main WordPress query:
{% set archive = posts %}
<h1>Archive ({{ archive.found_posts }} posts)</h1>
{% for post in archive %}
<h2>{{ post.title }}</h2>
{% endfor %}
{{ archive.pagination }}
A Variable block is only needed when you want pagination before the loop. If pagination comes after, assign a query name in the Loop block and reference it directly — no Variable block required.
Next steps
- Loop — loop concept and data sources
- Query Posts — all query arguments for posts and custom post types
- Variable block — store queries for reuse