Pagination

Navigate through paginated data with first-class Pagy integration and multiple display variants.

Key Features

  • Pagy Integration - First-class support for the Pagy gem
  • Standalone Mode - Use without Pagy with manual page config
  • 4 Variants - Simple, Numbered, Full, Compact
  • 5 Sizes - xs, sm, base, lg, xl
  • 3 Shapes - Rounded, Square, Pill
  • 4 Alignments - Left, Center, Right, Between
  • All Colors - Semantic and Tailwind colors for active page
  • Icon Only Mode - Hide text labels, show only icons
  • Page Jumper - Go-to-page input field
  • Turbo Integration - AJAX pagination with Turbo Frames
  • Info Display - "Showing X-Y of Z" text
  • Per-Page Selector - Optional items-per-page dropdown
  • Custom Labels - Override Previous/Next text
  • Full Accessibility - ARIA navigation landmark

Basic Usage

The simplest way to use pagination is with a Pagy object from your controller.

Basic Pagination with Pagy
# In your controller:
def index
  @pagy, @posts = pagy(Post.all, limit: 20)
end

# In your view:
<%= rui_pagination(pagy: @pagy) %>

Standalone Usage

Use pagination without Pagy by providing page configuration manually.

Standalone Pagination
<%= rui_pagination(
  current_page: 5,
  total_pages: 20,
  total_count: 200,
  base_url: posts_path,
  show_info: true
) %>

Variants

Choose from three display variants based on your UI needs.

Simple

Previous/Next buttons only - minimal and clean.

Numbered (Default)

Previous, page numbers with ellipsis, Next.

Full

First, Previous, page numbers, Next, Last - complete navigation.

Pagination Variants
<%# Simple - Previous/Next only %>
<%= rui_pagination(pagy: @pagy, variant: :simple) %>

<%# Numbered - With page numbers (default) %>
<%= rui_pagination(pagy: @pagy, variant: :numbered) %>

<%# Full - First/Previous/Numbers/Next/Last %>
<%= rui_pagination(pagy: @pagy, variant: :full) %>

<%# Compact - Minimal "Page X of Y" display %>
<%= rui_pagination(pagy: @pagy, variant: :compact) %>

Icon Only

Show only navigation icons without text labels. Ideal for tight spaces or when paired with page numbers.

Default (with text)

Icon only

Simple variant with icon only

Icon Only Mode
<%# Hide Previous/Next text, show only icons %>
<%= rui_pagination(pagy: @pagy, icon_only: true) %>

<%# Works with any variant %>
<%= rui_pagination(pagy: @pagy, variant: :simple, icon_only: true) %>
<%= rui_pagination(pagy: @pagy, variant: :full, icon_only: true) %>

Compact Variant

A minimal pagination display showing just "Page X of Y" with prev/next buttons. Perfect for mobile or space-constrained layouts.

Compact pagination

Compact with info display

Compact with different sizes

xs
sm
base
Compact Variant
<%# Minimal "Page X of Y" display %>
<%= rui_pagination(pagy: @pagy, variant: :compact) %>

<%# Compact with info %>
<%= rui_pagination(pagy: @pagy, variant: :compact, show_info: true) %>

<%# Smaller compact for tight spaces %>
<%= rui_pagination(pagy: @pagy, variant: :compact, size: :sm) %>

Alignment

Control horizontal alignment of pagination content. Useful when pagination doesn't fill the container width.

align: :left

align: :center

align: :right

align: :between

Pagination Alignment
<%# Left aligned %>
<%= rui_pagination(pagy: @pagy, align: :left, show_info: false) %>

<%# Center aligned %>
<%= rui_pagination(pagy: @pagy, align: :center, show_info: false) %>

<%# Right aligned %>
<%= rui_pagination(pagy: @pagy, align: :right, show_info: false) %>

<%# Space between (default) - info on left, nav on right %>
<%= rui_pagination(pagy: @pagy, align: :between, show_info: true) %>

Page Jumper

Add a "Go to page" input field that lets users jump directly to a specific page number.

How It Works

  • Type a page number and press Enter (or blur the field)
  • Automatically validates within range (1 to total pages)
  • Works with Turbo Frames when turbo_frame: is set

Pagination with jumper

Compact with jumper

Full pagination with info and jumper

Page Jumper
<%# Add go-to-page input %>
<%= rui_pagination(pagy: @pagy, show_jumper: true) %>

<%# Compact variant with jumper - minimal but powerful %>
<%= rui_pagination(pagy: @pagy, variant: :compact, show_jumper: true) %>

<%# Works with Turbo Frames %>
<%= rui_pagination(
  pagy: @pagy,
  show_jumper: true,
  turbo_frame: "posts-list"
) %>

Sizes

Five size variants to match your design.

xs

sm

base

lg

xl

Pagination Sizes
<%= rui_pagination(pagy: @pagy, size: :xs) %>
<%= rui_pagination(pagy: @pagy, size: :sm) %>
<%= rui_pagination(pagy: @pagy, size: :base) %>  <%# default %>
<%= rui_pagination(pagy: @pagy, size: :lg) %>
<%= rui_pagination(pagy: @pagy, size: :xl) %>

Shapes

Three shape variants for button corners.

rounded

square

pill

Pagination Shapes
<%= rui_pagination(pagy: @pagy, shape: :rounded) %>  <%# default %>
<%= rui_pagination(pagy: @pagy, shape: :square) %>
<%= rui_pagination(pagy: @pagy, shape: :pill) %>

Colors

The active page button uses the specified color. Supports all semantic and Tailwind colors.

primary
success
danger
warning
info
violet
pink
amber
Pagination Colors
<%# Semantic colors %>
<%= rui_pagination(pagy: @pagy, color: :primary) %>
<%= rui_pagination(pagy: @pagy, color: :success) %>
<%= rui_pagination(pagy: @pagy, color: :danger) %>

<%# Tailwind colors %>
<%= rui_pagination(pagy: @pagy, color: :violet) %>
<%= rui_pagination(pagy: @pagy, color: :pink) %>

Info Display

Show "Showing X-Y of Z" information alongside pagination.

With info (default when total_count provided)

Without info

Info Display
<%# Show "Showing 11-20 of 100" info %>
<%= rui_pagination(pagy: @pagy, show_info: true) %>

<%# Hide info text %>
<%= rui_pagination(pagy: @pagy, show_info: false) %>

Turbo Integration

Enable AJAX pagination with Turbo Frames for seamless page navigation without full reloads.

How It Works

  1. Wrap your content in a <turbo-frame> with an ID
  2. Pass that ID to turbo_frame: parameter
  3. Clicking pagination links updates only that frame
Turbo Frame Pagination
<%# Wrap content in turbo-frame %>
<turbo-frame id="posts-list">
  <% @posts.each do |post| %>
    <%= render post %>
  <% end %>

  <%# Pagination inside the frame %>
  <%= rui_pagination(
    pagy: @pagy,
    turbo_frame: "posts-list",
    turbo_action: :replace
  ) %>
</turbo-frame>

<%# Or pagination outside the frame targeting it %>
<%= rui_pagination(
  pagy: @pagy,
  turbo_frame: "posts-list"
) %>

Custom Labels

Override the default button text for internationalization or custom wording.

Custom Labels
<%= rui_pagination(
  pagy: @pagy,
  variant: :full,
  prev_text: "Back",
  next_text: "Forward",
  first_text: "Start",
  last_text: "End"
) %>

<%# For i18n %>
<%= rui_pagination(
  pagy: @pagy,
  prev_text: t("pagination.previous"),
  next_text: t("pagination.next")
) %>

Window Configuration

Control how many page numbers appear around the current page and at the edges.

Default (window: 2, outer_window: 1)

Large window (window: 4, outer_window: 2)

Minimal (window: 1, outer_window: 0)

Window Configuration
<%# window: pages shown around current page %>
<%# outer_window: pages shown at edges (first/last) %>

<%= rui_pagination(
  pagy: @pagy,
  window: 2,        # Show 2 pages before/after current
  outer_window: 1   # Show 1 page at start/end
) %>

Custom Styling

Override default styles using the class: parameter.

Available Class Overrides

  • class: - Applied to the wrapper element (merged with defaults)
  • Any HTML attribute via **options (id, data-*, aria-*, etc.)
Custom Styling
<%# Add background and padding to wrapper %>
<%= rui_pagination(
  pagy: @pagy,
  class: "p-4 bg-zinc-100 rounded-lg"
) %>

<%# Add custom data attributes %>
<%= rui_pagination(
  pagy: @pagy,
  id: "my-pagination",
  data: { controller: "my-pagination" }
) %>

With Table Component

When using the Table component, pagination is automatically rendered in the footer when you pass a pagy: object.

See the Table documentation for full table pagination examples including sorting, selection, and toolbar integration.

Table with Built-in Pagination
<%# Table automatically renders pagination when pagy is provided %>
<%= rui_table(pagy: @pagy) do |table| %>
  <% table.with_column(key: :name, label: "Name") %>
  <% table.with_column(key: :email, label: "Email") %>

  <% @users.each do |user| %>
    <% table.with_row(id: user.id, data: user) %>
  <% end %>
<% end %>

<%# Or use standalone pagination below the table %>
<%= rui_table do |table| %>
  ...
<% end %>

<%= rui_pagination(pagy: @pagy) %>

Accessibility

The Pagination component follows WAI-ARIA best practices.

ARIA Attributes

  • role="navigation" on the wrapper element
  • aria-label="Pagination navigation" for screen readers
  • aria-current="page" on the current page button
  • aria-disabled="true" on disabled prev/next buttons

Keyboard Navigation

  • Tab moves focus between pagination buttons
  • Enter / Space activates the focused button
  • Focus ring visible on all interactive elements

API Reference

rui_pagination

Pagination component for navigating through paginated data

Parameter Type Default Description
pagy Pagy Pagy object for automatic configuration
current_page Integer 1 Current page number (if no pagy)
total_pages Integer 1 Total number of pages (if no pagy)
total_count Integer Total item count (for info display)
base_url String current URL Base URL for pagination links
page_param Symbol :page URL parameter name for page number

Appearance

Visual styling options

Parameter Type Default Description
variant Symbol :numbered Display variant
:simple :numbered :full :compact
size Symbol :base Button size
:xs :sm :base :lg :xl
shape Symbol :rounded Button shape
:rounded :square :pill
color Symbol :primary Active page button color
align Symbol :between Content alignment
:left :center :right :between
icon_only Boolean false Show only icons on prev/next buttons (no text)

Info Display

Information text options

Parameter Type Default Description
show_info Boolean true Show 'Showing X-Y of Z' info
show_per_page Boolean false Show per-page selector dropdown
per_page_options Array [10, 25, 50, 100] Options for per-page selector
items_per_page Integer from pagy or 10 Current items per page
show_jumper Boolean false Show go-to-page input field

Window Configuration

Control page number display

Parameter Type Default Description
window Integer 2 Number of page links around current page
outer_window Integer 1 Number of page links at edges (first/last)

Turbo Integration

AJAX pagination options

Parameter Type Default Description
turbo_frame String Turbo Frame ID for AJAX updates
turbo_action Symbol :replace Turbo action type
:replace :advance

Custom Labels

Override default button text

Parameter Type Default Description
prev_text String "Previous" Previous button text
next_text String "Next" Next button text
first_text String "First" First button text (full variant)
last_text String "Last" Last button text (full variant)

Custom Styling

Override default styles

Parameter Type Default Description
class String Custom CSS classes for wrapper (merged with defaults)
id String Custom ID for the wrapper element
data Hash Custom data attributes