URLs
Pagy uses the current URL as the base to generate all the other page URLs. It retrieves it from the self.request when available, or from a :request option set to a Rack::Request or a simple Hash of :base_url, :path, :params (and a pagy :cookie value in case of Keynav pagination).
Pagy generates its specialized URLs ~20x faster than generic helpers like rails' url_for. When possible, it just replaces the page value, without recalculating every part of a URL.
These options give you full control over the URL composition for paginator and helper:
jsonapi: true- Enables JSON:API-compliant URLs with nested query string (e.g.,
?page[number]=2&page[size]=100). root_key: 'my_root'- Set it to enable nested URLs with nested query string
?my_root[page]=2&my_root[limit]=100)). Use it to handle multiple pagination objects in the same request. page_key: 'my_page'- Set it to change the key string used for the
:pagein URLs (default'page'). limit_key: 'my_limit'- Set it to change the key string used for the
:limitin URLs (default'limit').
absolute: true- Makes the URL absolute.
path: '/my_path'- Overrides the request path in pagination URLs. Use the path only (not the absolute URL). (see Override the request path)
fragment: '...'- URL fragment string.
querify: tweakSet it to a
Lambdato directly edit the passed string-keyed params hash itself. Its result is ignored.tweak = ->(q) { q.except!('not_useful').merge!('custom' => 'useful') }
No framework params!
Pagy ignores the request.params because they are modified differently by different frameworks (Rails, Sinatra, etc.). It can only rely on the request.GET and request.POST methods, which are consistent across all Rack environments.
No symbolic params!
The params that Pagy handles composing its URLs, are strictly string-keyed. That's how every gem/framework handles URLs, because it avoids the maintenance and performance overhead of converting symbols back and forth during URL composition.
Serving paginated collections is a retrieval action that does not modify data; therefore, it should rely on GET requests. Since most applications follow this standard, Pagy parses and produces GET URLs out of the box.
If you must use POST to retrieve paginated collections, you should build your own POST forms/requests using the data provided by Pagy (e.g., via the data_hash or instance readers). However, Pagy parses and handles POST request parameters out of the box without additional configuration.
Routers (like the Rails' one) allow defining parameters as part of the path (e.g., /items/:page)...
Pagy does not support, nor recommends dynamic path segments for the :page param.
Why?
The Cons are overwhelming.
Pros
Cons
This file is provided as a courtesy configuration
It is not an officially supported or tested feature, as it bypasses the standard, high-performance Pagy URL generation logic.
Use it at your own risk and extra maintenance!
# frozen_string_literal: true
# ################# IMPORTANT WARNING #################
# This setup forces Pagy to use the Rails `url_for` method,
# which is significantly slower (~20x) than Pagy's native URL generation.
# Use this file ONLY if you absolutely want to support the page param as a dynamic segment.
# (e.g. get '/comments(/:page)', to: 'comments#index').
# #####################################################
# USAGE
# initializers/pagy.rb
# require Pagy::ROOT.join('apps/enable_rails_page_segment.rb')
# config/routes.rb (example)
# get '/comments(/:page)', to: 'comments#index'
# Use plain Strings tokens instead of Pagy::EscapedValue strings
Pagy.send(:remove_const, :PAGE_TOKEN) ; Pagy::PAGE_TOKEN = '___PAGY_PAGE___'
Pagy.send(:remove_const, :LIMIT_TOKEN) ; Pagy::LIMIT_TOKEN = '___PAGY_LIMIT___'
# Require the pagy sources to override
require_relative '../lib/pagy/toolbox/paginators/method'
require_relative '../lib/pagy/modules/abilities/linkable'
class Pagy
# Switch to the `request.params` to get access to rails-added path parameters
module RequestOverride
def get_params(request)
request.params
end
end
Request.prepend RequestOverride
# Inject the caller context into the Pagy instance
module MethodOverride
def pagy(...)
super.tap { _1[0].instance_variable_set(:@context, self) }
end
end
Method.prepend MethodOverride
# Compose the final URL using `url_for`.
module LinkableOverride
def compose_url(absolute, _path, params, fragment)
params[:anchor] = fragment if fragment
params[:only_path] = !absolute
@context.url_for(params)
end
end
Linkable.prepend LinkableOverride
end