🏆 The Best Pagination Ruby Gem 🥇
✴ What’s new in 8.0+ ✴
- WARNING: The
foundation
,materialize
,semantic
anduikit
CSS extras have been discontinued and will be removed in v9 (See the details) - New Pagy Playground to showcase, clone and develop pagy APPs without any setup on your side (try the pagy demo)
- New
:max_pages
variable to limit the pagination regardless the actual count - Better frontend helpers
- Deprecate the legacy nav bar, add features to the default faster nav bar series
- See the Changelog for possible breaking changes
🚀 🚀 🚀 🚀 🚀
_Each dot in the visualization above represents the resources that Pagy consumes for one full rendering. The other gems consume
hundreds of times as much for the same rendering._
_The [IPS/Kb ratio](http://ddnexus.github.io/pagination-comparison/gems.html#efficiency-ratio) is calculated out of speed (IPS)
and Memory (Kb): it shows how well each gem uses each Kb of memory it allocates/consumes._
Notice: the above charts refers to the comparison of the basic `pagy v3.0.0` helper with `will_paginate v3.1.7`
and `kaminari v1.1.1`.
While it's not up-to-date, you can expect roughly similar results with the latest versions, maybe a bit less dramatic in
performance due to the multiple features added to pagy since v3 (e.g. customizable and translated aria-labels). However, consider
that the difference become A LOT bigger in favor of pagy if you use `*nav_js` helpers, `Pagy::Countless` or JSON and client side
pagination that are not part of the comparison because missing in the other gems.
See the [Detailed Gems Comparison](http://ddnexus.github.io/pagination-comparison/gems.html) for full details.
Code Structure
- Pagy has a very slim core code very easy to understand and use.
- It has a quite fat set of optional extras that you can explicitly require for very efficient and modular customization ( see extras)
- It has no dependencies: it produces its own HTML, URLs, i18n with its own specialized and fast code
- Its methods are accessible and overridable right where you use them (no pesky monkey-patching needed)
Unlike the other gems
- Pagy is very modular and does not load any unnecessary code ( see why…)_
- It doesn’t impose limits even with collections|scopes that already used
limit
andoffset
( see how…) - It raises
Pagy::OverflowError
exceptions that you can rescue from ( see how…) or use the overflow extra for a few ready to use common behaviors - It does not impose any difficult-to-override logic or output
😎 It’s easy to use and customize
Code for basic pagination...
```rb # Include it in the controllers (e.g. application_controller.rb) include Pagy::Backend # Include it in the helpers (e.g. application_helper.rb) include Pagy::Frontend # Wrap your collections with pagy in your actions @pagy, @records = pagy(Product.all) ``` Optionally set your defaults in the pagy initializer: ```rb # Optionally override some pagy default with your own in the pagy initializer Pagy::DEFAULT[:items] = 10 # items per page Pagy::DEFAULT[:size] = 9 # nav bar links # Better user experience handled automatically require 'pagy/extras/overflow' Pagy::DEFAULT[:overflow] = :last_page ``` ```erb <%# Render a view helper in your views (skipping nav links for empty pages) %> <%== pagy_nav(@pagy) if @pagy.pages > 1 %> ``` Or, choose from the following view helpers: | View Helper Name | Preview (Bootstrap Style shown) | |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------| | [`pagy_nav(@pagy)`](https://ddnexus.github.io/pagy/docs/api/frontend) | ![`pagy_nav`](/docs/assets/images/bootstrap_nav.png) | | [`pagy_nav_js(@pagy)`](https://ddnexus.github.io/pagy/docs/api/javascript/) | ![`pagy_nav_js`](/docs/assets/images/bootstrap_nav_js.png) | | [`pagy_info(@pagy)`](https://ddnexus.github.io/pagy/docs/api/frontend) | ![`pagy_info`](/docs/assets/images/pagy_info.png) | | [`pagy_combo_nav_js(@pagy)`](https://ddnexus.github.io/pagy/docs/api/javascript/) | ![`pagy_combo_nav_js`](/docs/assets/images/bootstrap_combo_nav_js.png) | | [`pagy_items_selector_js`](https://ddnexus.github.io/pagy/docs/api/javascript/) | ![`pagy_items_selector_js`](/docs/assets/images/items_selector_js.png) | | [`pagy_nav(@calendar[:year])`](https://ddnexus.github.io/pagy/docs/extras/calendar/)[`pagy_nav(@calendar[:month])`](https://ddnexus.github.io/pagy/docs/extras/calendar/)
(other units: `:quarter`, `:week`, `:day` and custom) | ![calendar extra](/docs/assets/images/calendar-app.png) | _(See the [Quick Start](https://ddnexus.github.io/pagy/quick-start))_
Customization for CSS frameworks...
```rb # Require a CSS framework extra in the pagy initializer (e.g. bootstrap) require 'pagy/extras/bootstrap' ``` ```erb <%# Use it in your views %> <%== pagy_bootstrap_nav(@pagy) %> ``` _(See all the [CSS Framework Extras](https://ddnexus.github.io/pagy/categories/frontend/))_Customization for special collections...
```rb # Require some special backend extra in the pagy initializer (e.g. elasticsearch_rails) require 'pagy/extras/elasticsearch_rails' # Extend your models (e.g. application_record.rb) extend Pagy::ElasticsearchRails # Use it in your actions response = Article.pagy_search(params[:q]) @pagy, @response = pagy_elasticsearch_rails(response) ``` _(See all the [Search Extras](https://ddnexus.github.io/pagy/categories/search/))_Customization for client-side|JSON rendering...
```ruby # Require the metadata extra in the pagy initializer require 'pagy/extras/metadata' # Use it in your actions pagy, records = pagy(Product.all) render json: { data: records, pagy: pagy_metadata(pagy) } ``` _(See all the [Backend Tools](https://ddnexus.github.io/pagy/categories/backend/))_Customization for headers pagination for APIs...
```ruby # Require the headers extra in the pagy initializer require 'pagy/extras/headers' # Use it in your actions pagy, records = pagy(Product.all) pagy_headers_merge(pagy) render json: records ``` _(See all the [Backend Tools](https://ddnexus.github.io/pagy/categories/backend/))_Customization for JSON:API pagination...
```ruby # Require the jsonapi extra in the pagy initializer require 'pagy/extras/jsonapi' # Use it in your actions pagy, records = pagy(Product.all) render json: { data: records, links: pagy_jsonapi_links(pagy) } # besides the query params will be nested. E.g.: ?page[number]=2&page[size]=100 ``` _(See all the [Backend Tools](https://ddnexus.github.io/pagy/categories/backend/))_More customization with extras...
Extras add special options and manage different components, behaviors, Frontend or Backend environments... usually by just requiring them (and optionally overriding some default). ### Backend Extras - [arel](https://ddnexus.github.io/pagy/docs/extras/arel): Provides better performance of grouped ActiveRecord collections - [array](https://ddnexus.github.io/pagy/docs/extras/array): Paginate arrays efficiently. - [calendar](https://ddnexus.github.io/pagy/docs/extras/calendar): Add pagination filtering by calendar time unit (year, quarter, month, week, day, custom) - [countless](https://ddnexus.github.io/pagy/docs/extras/countless): Paginate without the need of any count, saving one query per rendering - [elasticsearch_rails](https://ddnexus.github.io/pagy/docs/extras/elasticsearch_rails): Paginate `ElasticsearchRails` response objects - [headers](https://ddnexus.github.io/pagy/docs/extras/headers): Add RFC-8288 compliant http response headers (and other helpers) useful for API pagination - [jsonapi](https://ddnexus.github.io/pagy/docs/extras/jsonapi): Implement the [JSON:API](https://jsonapi.org) specifications for pagination - [meilisearch](https://ddnexus.github.io/pagy/docs/extras/meilisearch): Paginate `Meilisearch` results - [metadata](https://ddnexus.github.io/pagy/docs/extras/metadata): Provides the pagination metadata to Javascript frameworks like Vue.js, react.js, etc. - [searchkick](https://ddnexus.github.io/pagy/docs/extras/searchkick): Paginate `Searchkick::Results` objects ### Extra Features and Tools - [Pagy::Console](https://ddnexus.github.io/pagy/docs/api/console/): Use pagy in the irb/rails console even without any app nor configuration - [gearbox](https://ddnexus.github.io/pagy/docs/extras/gearbox/): Automatically change the number of items per page depending on the page number - [i18n](https://ddnexus.github.io/pagy/docs/extras/i18n): Use the `I18n` gem instead of the faster pagy-i18n implementation - [items](https://ddnexus.github.io/pagy/docs/extras/items): Allow the client to request a custom number of items per page with an optional selector UI - [overflow](https://ddnexus.github.io/pagy/docs/extras/overflow): Allow easy handling of overflowing pages - [standalone](https://ddnexus.github.io/pagy/docs/extras/standalone): Use pagy without any request object, nor Rack environment/gem, nor any defined `params` method - [trim](https://ddnexus.github.io/pagy/docs/extras/trim): Remove the `page=1` param from the first page link
See also the How To Page
Documentation
- Migrate from WillPaginate and Kaminari (practical guide)
- Quick Start
- Documentation
- How To (quick recipes)
- Changelog
- Deprecations
- How Pagy’s Docs work?
Posts and tutorials
- Migrate from WillPaginate and Kaminari (practical guide)
- Detailed Gems Comparison (charts and analysis)
- Benchmarks and Memory Profiles Source (Rails app repository)
- Faster Pagination with Pagy introductory tutorial by Sirajus Salekin
- Pagination with Pagy by Tiago Franco
- Quick guide for Pagy with Sinatra and Sequel by Victor Afanasev
- Integrating Pagy with Hanami by Paweł Świątkowski
- Stateful Tabs with Pagy by Chris Seelus
- Endless Scroll / Infinite Loading with Turbo Streams & Stimulus by Stefan Wienert.
- Build Load More Pagination with Pagy and Rails Hotwire by Maful. ( This tutorial shows how you can turbo_stream with GET requests).
- Pagination with Hotwire by Jonathan Greenberg
- Pagination and infinite scrolling with Rails and the Hotwire stack by David Colby
- Building a dynamic data grid with search and filters using rails, hotwire and ransack by Benito Serna.
- Pagination for Beginners: What is it? Why bother? by Ben Koshy.
- Handling Pagination When POSTing Complex Search Forms by Ben Koshy.
- How to Override pagy methods only in specific circumstances by Ben Koshy.
- How to make your pagination links sticky + bounce at the bottom of your page by Ben Koshy.
- 日本語の投稿
- 한국어 튜토리얼