Numbered Pagination
A numbered page strip that collapses long runs to an ellipsis.
6 frameworksIntermediate
Two step links either side of a live "Page 3 of 10" readout.
<!--
No number list at all - two links and a position readout. Worth preferring
over numbered pages when the total is unknown or unstable (a live feed, a
cursor-paged API), because a numbered strip promises a page 7 that may not
exist by the time it is clicked.
"Page 3 of 10" is a real text node between the two links, not a title
attribute, so it is the accessible answer to "where am I" - the piece a
bare Previous/Next pair is usually missing.
-->
<nav class="prevnext" aria-label="Pagination">
<a class="prevnext__link" href="?page=2" rel="prev">
<svg class="prevnext__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="m15 18-6-6 6-6" />
</svg>
Previous
</a>
<p class="prevnext__status" aria-live="polite">Page 3 of 10</p>
<a class="prevnext__link" href="?page=4" rel="next">
Next
<svg class="prevnext__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="m9 18 6-6-6-6" />
</svg>
</a>
</nav>| Prop | Type | Default | Description |
|---|---|---|---|
currentPagerequired | number | - | The active page number, starting at 1. |
totalPagesrequired | number | - | How many pages exist in total. |
buildHrefrequired | (page: number) => string | - | Builds the URL for a page number, so pages stay real links. |
ariaLabel | string | 'Pagination' | The button's accessible name. Required for icon-only buttons. |
className | string | - | Additional classes merged onto the root element. |
Prefer this over a numbered strip when the total is unknown or unstable - a cursor-paged API, a feed that grows while it is read - because a numbered strip promises a page 7 that may not exist by the time someone clicks it. The readout is the part most Previous/Next pairs are missing: without it the control answers "where can I go" but never "where am I", and it has to be a real text node rather than a `title` attribute to be that answer for everyone. It sits in a polite live region so the position is re-announced after a client-side navigation, and polite rather than assertive because the change is the user's own doing and should queue behind whatever they are already hearing. `rel="prev"` and `rel="next"` are not decoration; they tell crawlers and reader modes how the sequence is ordered.