Skip to main content
  1. X-GOVUK projects
  2. GOV.UK Components
  3. Pagination

Pagination

Help users navigate forwards and backwards through a series of pages.

Pagination is a complex problem and it goes beyond the scope of this gem. Instead of implementing something from scratch this library uses Pagy, a small and modular pagination gem for Ruby.

Basic pagination with a Pagy object

Pagination links can be generated by passing a Pagy object directly to the component.

Input

= govuk_pagination(pagy: pagy)
<%= govuk_pagination(pagy: pagy) %>
{ pagy: Pagy.new(count: 100, page: 2) }

Output

<nav aria-label="Pagination" class="govuk-pagination">
  <div class="govuk-pagination__prev">
    <a href="?page=1" class="govuk-link govuk-pagination__link" rel="prev">
      <svg class="govuk-pagination__icon govuk-pagination__icon--prev" xmlns="http://www.w3.org/2000/svg" height="13" width="15" focusable="false" viewBox="0 0 15 13" aria-hidden="true">
        <path d="m6.5938-0.0078125-6.7266 6.7266 6.7441 6.4062 1.377-1.449-4.1856-3.9768h12.896v-2h-12.984l4.2931-4.293-1.414-1.414z" />
      </svg>
      <span class="govuk-pagination__link-title govuk-pagination__link-title--decorated">
        Previous<span class="govuk-visually-hidden">
          page
        </span>
      </span>
    </a>
  </div>
  <ul class="govuk-pagination__list">
    <li class="govuk-pagination__item" aria-label="Page 1">
      <a href="?page=1" class="govuk-link govuk-pagination__link">
        1
      </a>
    </li>
    <li class="govuk-pagination__item govuk-pagination__item--current" aria-label="Page 2">
      <a href="?page=2" class="govuk-link govuk-pagination__link">
        2
      </a>
    </li>
    <li class="govuk-pagination__item" aria-label="Page 3">
      <a href="?page=3" class="govuk-link govuk-pagination__link">
        3
      </a>
    </li>
    <li class="govuk-pagination__item" aria-label="Page 4">
      <a href="?page=4" class="govuk-link govuk-pagination__link">
        4
      </a>
    </li>
    <li class="govuk-pagination__item" aria-label="Page 5">
      <a href="?page=5" class="govuk-link govuk-pagination__link">
        5
      </a>
    </li>
  </ul>
  <div class="govuk-pagination__next">
    <a href="?page=3" class="govuk-link govuk-pagination__link" rel="next">
      <span class="govuk-pagination__link-title govuk-pagination__link-title--decorated">
        Next<span class="govuk-visually-hidden">
          page
        </span>
      </span>
      <svg class="govuk-pagination__icon govuk-pagination__icon--next" xmlns="http://www.w3.org/2000/svg" height="13" width="15" focusable="false" viewBox="0 0 15 13" aria-hidden="true">
        <path d="m8.107-0.0078125-1.4136 1.414 4.2926 4.293h-12.986v2h12.896l-4.1855 3.9766 1.377 1.4492 6.7441-6.4062-6.7246-6.7266z" />
      </svg>
    </a>
  </div>
</nav>

When there are lots of pages

Pagy is very configurable and projects might want to tweak the defaults to suit their needs.

To match the guidance in the Design System documentation, Pagy’s default size parameter should be set to [1, 1, 1, 1].

This means that:

  • 1 page is shown at the beginning
  • 1 page is shown before the current page
  • 1 page is shown after the current page
  • 1 page is shown at the end

Input

= govuk_pagination(pagy: pagy)
<%= govuk_pagination(pagy: pagy) %>
{ pagy: Pagy.new(count: 100, page: 9, size: [1, 1, 1, 1], items: 5) }

Output

<nav aria-label="Pagination" class="govuk-pagination">
  <div class="govuk-pagination__prev">
    <a href="?page=8" class="govuk-link govuk-pagination__link" rel="prev">
      <svg class="govuk-pagination__icon govuk-pagination__icon--prev" xmlns="http://www.w3.org/2000/svg" height="13" width="15" focusable="false" viewBox="0 0 15 13" aria-hidden="true">
        <path d="m6.5938-0.0078125-6.7266 6.7266 6.7441 6.4062 1.377-1.449-4.1856-3.9768h12.896v-2h-12.984l4.2931-4.293-1.414-1.414z" />
      </svg>
      <span class="govuk-pagination__link-title govuk-pagination__link-title--decorated">
        Previous<span class="govuk-visually-hidden">
          page
        </span>
      </span>
    </a>
  </div>
  <ul class="govuk-pagination__list">
    <li class="govuk-pagination__item" aria-label="Page 1">
      <a href="?page=1" class="govuk-link govuk-pagination__link">
        1
      </a>
    </li>
    <li class="govuk-pagination__item govuk-pagination__item--ellipses"></li>
    <li class="govuk-pagination__item" aria-label="Page 8">
      <a href="?page=8" class="govuk-link govuk-pagination__link">
        8
      </a>
    </li>
    <li class="govuk-pagination__item govuk-pagination__item--current" aria-label="Page 9">
      <a href="?page=9" class="govuk-link govuk-pagination__link">
        9
      </a>
    </li>
    <li class="govuk-pagination__item" aria-label="Page 10">
      <a href="?page=10" class="govuk-link govuk-pagination__link">
        10
      </a>
    </li>
    <li class="govuk-pagination__item govuk-pagination__item--ellipses"></li>
    <li class="govuk-pagination__item" aria-label="Page 20">
      <a href="?page=20" class="govuk-link govuk-pagination__link">
        20
      </a>
    </li>
  </ul>
  <div class="govuk-pagination__next">
    <a href="?page=10" class="govuk-link govuk-pagination__link" rel="next">
      <span class="govuk-pagination__link-title govuk-pagination__link-title--decorated">
        Next<span class="govuk-visually-hidden">
          page
        </span>
      </span>
      <svg class="govuk-pagination__icon govuk-pagination__icon--next" xmlns="http://www.w3.org/2000/svg" height="13" width="15" focusable="false" viewBox="0 0 15 13" aria-hidden="true">
        <path d="m8.107-0.0078125-1.4136 1.414 4.2926 4.293h-12.986v2h12.896l-4.1855 3.9766 1.377 1.4492 6.7441-6.4062-6.7246-6.7266z" />
      </svg>
    </a>
  </div>
</nav>

For smaller numbers of pages

Use ‘Previous’ and ‘Next’ links to let users navigate through a small number of pages. Stack the links vertically with block_mode: true so they’re more obvious to screen magnifier users when they’re zoomed in.

Input

= govuk_pagination(block_mode: true) do |p|
  - p.with_previous_page(text: "Chapter 3", label_text: "Edmund and the Wardrobe", href: "#")
  - p.with_next_page(text: "Chapter 5", label_text: "Back on This Side of the Door", href: "#")
<%= govuk_pagination(block_mode: true) do |p|
p.with_previous_page(text: "Chapter 3", label_text: "Edmund and the Wardrobe", href: "#")
p.with_next_page(text: "Chapter 5", label_text: "Back on This Side of the Door", href: "#")
end %>

Output

<nav aria-label="Pagination" class="govuk-pagination govuk-pagination--block">
  <div class="govuk-pagination__prev">
    <a href="#" class="govuk-link govuk-pagination__link" rel="prev">
      <svg class="govuk-pagination__icon govuk-pagination__icon--prev" xmlns="http://www.w3.org/2000/svg" height="13" width="15" focusable="false" viewBox="0 0 15 13" aria-hidden="true">
        <path d="m6.5938-0.0078125-6.7266 6.7266 6.7441 6.4062 1.377-1.449-4.1856-3.9768h12.896v-2h-12.984l4.2931-4.293-1.414-1.414z" />
      </svg>
      <span class="govuk-pagination__link-title">
        Chapter 3
      </span>
      <span class="govuk-visually-hidden">
        :
      </span>
      <span class="govuk-pagination__link-label">
        Edmund and the Wardrobe
      </span>
    </a>
  </div>
  <ul class="govuk-pagination__list">
  </ul>
  <div class="govuk-pagination__next">
    <a href="#" class="govuk-link govuk-pagination__link" rel="next">
      <svg class="govuk-pagination__icon govuk-pagination__icon--next" xmlns="http://www.w3.org/2000/svg" height="13" width="15" focusable="false" viewBox="0 0 15 13" aria-hidden="true">
        <path d="m8.107-0.0078125-1.4136 1.414 4.2926 4.293h-12.986v2h12.896l-4.1855 3.9766 1.377 1.4492 6.7441-6.4062-6.7246-6.7266z" />
      </svg>
      <span class="govuk-pagination__link-title">
        Chapter 5
      </span>
      <span class="govuk-visually-hidden">
        :
      </span>
      <span class="govuk-pagination__link-label">
        Back on This Side of the Door
      </span>
    </a>
  </div>
</nav>

Full manual control

If you have specific requirements that aren’t met by Pagy you can take full control of the pagination component’s contents by calling the slots individually.

You can use this approach to add custom HTML attributes to the next, previous and item slots or to add a custom ellipsis layout.

Input

= govuk_pagination do |p|
  - p.with_previous_page(href: "#", text: "Previous events", html_attributes: { id: 'page-prev' })
  - p.with_items(item_data)
  - p.with_next_page(href: "#", text: "Next events", html_attributes: { id: 'page-next' })
<%= govuk_pagination do |p|
p.with_previous_page(href: "#", text: "Previous events", html_attributes: { id: 'page-prev' })
p.with_items(item_data)
p.with_next_page(href: "#", text: "Next events", html_attributes: { id: 'page-next' })
end %>
{
  item_data:
    [
      { href: "#", number: 10, html_attributes: { id: 'page-10' } },
      { ellipsis: true },
      { href: "#", number: 20, html_attributes: { id: 'page-20' } },
      { ellipsis: true },
      { href: "#", number: 30, current: true, html_attributes: { id: 'page-30' } },
      { ellipsis: true },
      { href: "#", number: 40, html_attributes: { id: 'page-40' } },
    ]
}

Output

<nav aria-label="Pagination" class="govuk-pagination">
  <div class="govuk-pagination__prev" id="page-prev">
    <a href="#" class="govuk-link govuk-pagination__link" rel="prev">
      <svg class="govuk-pagination__icon govuk-pagination__icon--prev" xmlns="http://www.w3.org/2000/svg" height="13" width="15" focusable="false" viewBox="0 0 15 13" aria-hidden="true">
        <path d="m6.5938-0.0078125-6.7266 6.7266 6.7441 6.4062 1.377-1.449-4.1856-3.9768h12.896v-2h-12.984l4.2931-4.293-1.414-1.414z" />
      </svg>
      <span class="govuk-pagination__link-title govuk-pagination__link-title--decorated">
        Previous events
      </span>
    </a>
  </div>
  <ul class="govuk-pagination__list">
    <li class="govuk-pagination__item" aria-label="Page 10" id="page-10">
      <a href="#" class="govuk-link govuk-pagination__link">
        10
      </a>
    </li>
    <li class="govuk-pagination__item govuk-pagination__item--ellipses"></li>
    <li class="govuk-pagination__item" aria-label="Page 20" id="page-20">
      <a href="#" class="govuk-link govuk-pagination__link">
        20
      </a>
    </li>
    <li class="govuk-pagination__item govuk-pagination__item--ellipses"></li>
    <li class="govuk-pagination__item govuk-pagination__item--current" aria-label="Page 30" id="page-30">
      <a href="#" class="govuk-link govuk-pagination__link">
        30
      </a>
    </li>
    <li class="govuk-pagination__item govuk-pagination__item--ellipses"></li>
    <li class="govuk-pagination__item" aria-label="Page 40" id="page-40">
      <a href="#" class="govuk-link govuk-pagination__link">
        40
      </a>
    </li>
  </ul>
  <div class="govuk-pagination__next" id="page-next">
    <a href="#" class="govuk-link govuk-pagination__link" rel="next">
      <span class="govuk-pagination__link-title govuk-pagination__link-title--decorated">
        Next events
      </span>
      <svg class="govuk-pagination__icon govuk-pagination__icon--next" xmlns="http://www.w3.org/2000/svg" height="13" width="15" focusable="false" viewBox="0 0 15 13" aria-hidden="true">
        <path d="m8.107-0.0078125-1.4136 1.414 4.2926 4.293h-12.986v2h12.896l-4.1855 3.9766 1.377 1.4492 6.7441-6.4062-6.7246-6.7266z" />
      </svg>
    </a>
  </div>
</nav>