Choosing Between Jekyll Pagination Options: Core vs. jekyll-paginate-v2
Compare Jekyll's built-in paginate with jekyll-paginate-v2 for 500+ posts. Core only paginates the main index; v2 adds category/tag/collection pagination, trail links, and JSON output but multiplies output files ~5× and needs GitHub Actions. Includes config, layout, and verification steps.
18 Aug 2026, 07:02 UTC

The Decision
You need pagination for a Jekyll blog with 500+ posts. The built-in jekyll-paginate handles a simple index page, but you also want category pages, tag archives, and possibly author or series collections — each paginated independently. The choice determines how many HTML files you generate, whether you can stay on GitHub Pages' default build, and how much template logic you maintain.
Constraints at a Glance
| Constraint | jekyll-paginate (core) | jekyll-paginate-v2 |
|---|---|---|
| Scope | Single page only (usually index.html) | Collections, categories, tags, data files, custom layouts |
| Navigation | Previous/next only | First, previous, next, last (trail) |
| Template variable | paginator | pagination (richer) + paginator for compat |
| GitHub Pages default build | Supported | Not supported — requires Actions or local build |
| Output files (500 posts, 10/page, 5 categories) | ~50 | ~250 (5× more) |
| Build time impact | Baseline | Proportional to total paginated pages |
| Collection requirement | N/A | output: true in _config.yml |
Trade-offs
Stick with core when
- You only paginate the main blog index.
- You deploy to GitHub Pages and want zero-config builds.
- Your site is small enough that 50 pages is the ceiling.
Switch to jekyll-paginate-v2 when
- You need paginated category/tag/author archives.
- You want trail navigation (first/last links) for better UX.
- You're building a headless front-end and need JSON pagination output.
- You accept GitHub Actions or local
_sitepushes for deployment.
Concrete Configuration: 500-Post Blog with Category Pagination
Assume a site with posts in _posts/, five categories (tech, design, process, tools, career), and 10 posts per page.
1. Gemfile
source "https://rubygems.org"
gem "jekyll", "~> 4.3"
gem "jekyll-paginate-v2", "~> 3.0"
# Remove jekyll-paginate if present
Run bundle install from the site root (requires write access to vendor/bundle or system gems).
2. _config.yml
plugins:
- jekyll-paginate-v2
pagination:
enabled: true
per_page: 10
permalink: "/blog/page/:num/"
title: ":title - Page :num"
limit: 0
sort_field: "date"
sort_reverse: true
category:
enabled: true
per_page: 10
permalink: "/category/:name/page/:num/"
title: ":name - Page :num"
tag:
enabled: true
per_page: 10
permalink: "/tag/:name/page/:num/"
title: ":name - Page :num"
collections:
posts:
output: true # required for v2 to paginate this collection
The category: and tag: blocks generate paginated archives automatically. Each category gets its own page series under /category/tech/page2.html, etc.
3. Category Layout (_layouts/category.html)
--- layout: default ---
{{ page.title }}
{% for post in pagination.posts %}
- {{ post.title }} {{ post.date | date: "%b %d, %Y" }}
{% endfor %}
{% if pagination.previous_page %}
« Previous
{% endif %}
{% if pagination.next_page %}
Next »
{% endif %}
{% if pagination.total_pages > 1 %}
Page {{ pagination.page }} of {{ pagination.total_pages }}
{% endif %}
Note the pagination variable (not paginator). It exposes posts, page, total_pages, previous_page, next_page, first_page, last_page, and corresponding _path helpers.
4. Build and Verify
# From site root
bundle exec jekyll build
# Check output count
find _site -name "page*.html" | wc -l
# Expect ~250 files for 5 categories × 10 pages each + main index
# Inspect a category page
cat _site/category/tech/page2.html
Run these commands in the project directory with your Ruby/Bundler environment active. No elevated permissions needed. Expected check: page2.html exists and contains the second batch of tech posts. Risk: if output: true is missing on the collection, v2 silently skips pagination — verify _site/category/ directories exist.
GitHub Pages Deployment
GitHub Pages' default build (as of 2024) uses a frozen plugin whitelist. jekyll-paginate-v2 is not on it. Two paths:
- GitHub Actions: Add a workflow (
/.github/workflows/jekyll.yml) that runsbundle exec jekyll buildand deploys_site/to thegh-pagesbranch or Pages artifact. This is the recommended path for v2 users. - Local build + push: Run
jekyll buildlocally, commit the generated_site/folder to a deploy branch, and point Pages to that branch. Simpler but commits build artifacts.
Verify the whitelist yourself at https://pages.github.com/versions/ — it changes occasionally.
Performance Check
# Measure build time
time bundle exec jekyll build
# Compare output size
du -sh _site
Run both with core paginate and with v2 to quantify the difference. For 500 posts, expect v2 to take 2–3× longer and produce 5× more files. If build time exceeds your CI timeout (often 10–15 min on free tiers), consider limiting pagination to the main index and top categories only.
Limitations & Gotchas
- Variable collision: Mixing
paginatorandpaginationin the same layout causes confusion. Pick one per layout. - Silent skip: Collections without
output: trueproduce no paginated pages — no error, just missing output. - Trail pagination complexity: First/last links require conditional logic for edge cases (page 1, last page, single page). Test all three states.
- No incremental regeneration: Jekyll 4.x does not incrementally rebuild paginated pages when a single post changes. Full rebuild required.
Rollback
If you switch to v2 and need to revert: remove jekyll-paginate-v2 from Gemfile and plugins list, restore jekyll-paginate, revert _config.yml to paginate: and paginate_path: keys, and change templates back to paginator. Run bundle install and rebuild. No database or persistent state to clean.
Quick Validation Checklist
- Main index paginates at
/blog/page2.html - Each category has
/category/name/page2.htmlwith correct posts - Trail links (first/prev/next/last) appear and resolve correctly
- GitHub Actions workflow passes (if using Actions)
- Build time and
_sitesize are within your limits
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.