Pagination without visible progress context — no current page number, no total page count — leaves users navigating blind. Under ISO 25010:2011 reliability, an application that crashes or returns an unhandled error on an out-of-range page number has a reliability defect. The failure surface is trivially reachable: any user who manually edits ?page=999 in a URL, or who follows a stale link to a page that no longer exists, hits the boundary. A crash response (500, unhandled exception, blank page) signals to search engine crawlers and users alike that the application is fragile.
High because missing page context disorients users and out-of-bounds page requests that crash the application create a reliability defect visible to both users and crawlers.
Clamp the requested page to [1, maxPage] on the server before querying, and render page progress explicitly in components/Pagination.tsx.
// Server: clamp before querying
const maxPage = Math.ceil(totalCount / pageSize)
const safePage = Math.min(Math.max(1, requestedPage), maxPage)
// components/Pagination.tsx
<span>Page {currentPage} of {totalPages}</span>
<button disabled={currentPage === 1} onClick={() => onPageChange(currentPage - 1)}>
Previous
</button>
<button disabled={currentPage === totalPages} onClick={() => onPageChange(currentPage + 1)}>
Next
</button>
Never pass an unclamped page number to OFFSET — out-of-range offsets return empty results silently or, worse, trigger database errors if the offset exceeds integer bounds.
ID: directory-search-discovery.pagination-url.pagination-ux
Severity: high
What to look for: Enumerate all relevant files and Examine the pagination control (if present). Check whether it displays the current page number (e.g., "Page 3 of 10") and total page count. Try navigating to an invalid page number (e.g., manually edit the URL to page=999). Verify the application either shows an error, redirects to the last valid page, or displays an empty/no-results state gracefully (not a crash).
Pass criteria: At least 1 implementation must be present. Pagination shows current page and total pages. Invalid page numbers are handled gracefully (error message, redirect to last page, or empty state — not a crash).
Fail criteria: Pagination does not show current page or total pages, or invalid page numbers cause an error or unexpected behavior.
Skip (N/A) when: Pagination is not implemented or results fit on a single page. Signal: no pagination control found or API returns all results without paging.
Detail on fail: "Pagination shows 'Next' and 'Previous' buttons but no page numbers or total page count." or "Navigating to page=999 shows an error or crashes the page."
Remediation: Implement clear pagination with bounds checking:
// components/Pagination.tsx
export function Pagination({ currentPage, totalPages, onPageChange }) {
const prevPage = Math.max(1, currentPage - 1)
const nextPage = Math.min(totalPages, currentPage + 1)
return (
<div className="flex justify-center items-center gap-4">
<button
disabled={currentPage === 1}
onClick={() => onPageChange(prevPage)}
>
Previous
</button>
<span>
Page {currentPage} of {totalPages}
</span>
<button
disabled={currentPage === totalPages}
onClick={() => onPageChange(nextPage)}
>
Next
</button>
</div>
)
}
// In your page component
const maxPage = Math.ceil(totalCount / pageSize)
const safePage = Math.min(Math.max(1, requestedPage), maxPage)
if (safePage !== requestedPage) {
// Optionally redirect to the valid page
}
Validate the requested page number on the server and return only valid pages.