Part 76: Enhancing Pagination in Next.js: A Step-by-Step Guide

[App] Pagination

[App] Pagination

Pagination is a key feature for improving user experience on websites with large data sets. In this guide, we'll enhance our pagination component in a Next.js application, focusing on disabling navigation links at the boundaries and improving the visual appearance and accessibility of the pagination UI.

Step 1: Refactor to a Separate Component

To handle the increasing complexity of our pagination logic and UI, the first step is to refactor the pagination code into a separate component. This not only improves code organization but also makes it reusable across different pages.

Creating the PaginationBar Component

  1. Create a New File: Under the components directory, create a new file named PaginationBar.jsx.

  2. Move Existing Code: Transfer the pagination code from ReviewsPage to this new component.

  3. Component Props: The PaginationBar component will receive page, pageCount, and href as props. The href prop specifies the base path for page navigation links.

// components/PaginationBar.jsx
import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/20/solid';
import Link from 'next/link';

export default function PaginationBar({ href, page, pageCount }) {
  return (
    <div className="flex gap-2 items-center pb-3">
      <PaginationLink href={`${href}?page=${page - 1}`} enabled={page > 1}>
        <ChevronLeftIcon className="h-5 w-5" />
        <span className="sr-only">Previous Page</span>
      </PaginationLink>
      <span>Page {page} of {pageCount}</span>
      <PaginationLink href={`${href}?page=${page + 1}`} enabled={page < pageCount}>
        <ChevronRightIcon className="h-5 w-5" />
        <span className="sr-only">Next Page</span>
      </PaginationLink>
    </div>
  );
}

Step 2: Enhance Visual Appearance with Icons

Improving the visual appearance of pagination controls can significantly enhance user experience. We'll replace the simple text indicators with icons, making the links more intuitive.

Using Icons for Navigation

  1. Icons: Use icons like ChevronLeftIcon and ChevronRightIcon from a popular icon library for the previous and next page links, respectively.

  2. Style Consistency: Apply consistent styles to the pagination links to match other UI elements, such as buttons.

function PaginationLink({ children, enabled, href }) {
  if (!enabled) {
    return (
      <span className="border cursor-not-allowed rounded text-slate-300 text-sm">
        {children}
      </span>
    );
  }
  return (
    <Link href={href}
      className="border rounded text-slate-500 text-sm hover:bg-orange-100 hover:text-slate-700">
      {children}
    </Link>
  );
}

To prevent users from navigating beyond the available pages, we need to disable the "Previous" link on the first page and the "Next" link on the last page.

  1. Conditional Rendering: Use a boolean enabled prop to conditionally render either a clickable Link or a non-clickable span.

  2. Boundary Conditions: Determine enablement based on the current page number and the total number of pages (pageCount).

<PaginationLink href={`${href}?page=${page - 1}`} enabled={page > 1}>
  <ChevronLeftIcon className="h-5 w-5" />
  <span className="sr-only">Previous Page</span>
</PaginationLink>

<PaginationLink href={`${href}?page=${page + 1}`} enabled={page < pageCount}>
  <ChevronRightIcon className="h-5 w-5" />
  <span className="sr-only">Next Page</span>
</PaginationLink>

Accessibility Enhancements

To ensure our pagination is accessible to all users, including those using screen readers, we should add descriptive text to icons.

Improving Accessibility

  1. Screen Reader Text: Use the sr-only class from Tailwind CSS to include text that is only visible to screen readers.

  2. Descriptive Text: Add span elements with descriptive text within the PaginationLink component.

<span className="sr-only">Previous Page</span>
<span className="sr-only">Next Page</span>

Conclusion

By refactoring our pagination into a separate component, enhancing its visual appearance with icons, and ensuring accessibility, we've significantly improved the user experience of our Next.js application. While our implementation is functional, further accessibility enhancements and UI refinements can be explored to create a truly polished application.

Last updated