# Part 75: Implementing Pagination in Next.js: A Step-by-Step Guide

<figure><img src="https://159896965-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3LclXKUpANLoSt8DPdYV%2Fuploads%2FJK8G3Yjm1qHwjGSqwUcV%2F1675674296261.jpeg?alt=media&#x26;token=989182c4-9098-4bba-8dd9-52aeb4b0f941" alt=""><figcaption><p>[App] Pagination</p></figcaption></figure>

When dealing with large amounts of data, pagination is a crucial feature that enhances user experience by organizing content into manageable sections. In this guide, we'll walk through implementing pagination for a Reviews page in a Next.js application, allowing users to navigate through all available reviews efficiently. Along the way, we'll also explore some useful features of Next.js.

### Setting Up the Pagination UI

The first step in adding pagination is to create a simple user interface that includes controls to navigate between pages.

**Step 1: Design the Pagination Interface**

The goal here is to create a user interface that allows users to navigate between different pages of reviews.

* **Navigation Links**: We add a `div` that contains links for navigating to the previous and next pages, as well as a display for the current page number.

  ```jsx
  <div className="flex gap-2 pb-3">
    {pagination.page > 1 && (
      <Link href={`/reviews?page=${pagination.page - 1}`}>&lt; Prev</Link>
    )}
    <span>Page {pagination.page} of {pagination.pageCount}</span>
    {pagination.page < pagination.pageCount && (
      <Link href={`/reviews?page=${pagination.page + 1}`}>Next &gt;</Link>
    )}
  </div>
  ```

  * **Previous Link**: Displayed only if the current page (`pagination.page`) is greater than 1.
  * **Next Link**: Displayed only if the current page is less than the total number of pages (`pagination.pageCount`).
  * **Current Page Indicator**: Shows the current page number and the total number of pages.
* **Styling**: The `flex` class is used to arrange elements in a row, `gap-2` adds space between them, and `pb-3` adds padding at the bottom for better visual separation.

#### Managing Page Navigation

**Step 2: Handle URL Parameters**

Next.js provides a way to handle URL parameters through the `searchParams` object, which includes query string parameters.

* **Extract and Parse Page Parameter**: We extract the `page` parameter and convert it to an integer. If the parameter is invalid or missing, it defaults to 1.

  ```jsx
  function parsePageParam(paramValue) {
    if (paramValue) {
      const page = parseInt(paramValue);
      if (isFinite(page) && page > 0) {
        return page;
      }
    }
    return 1;
  }
  ```
* **Use in Component**: Within the `ReviewsPage` component, we determine the current page using this function:

  ```jsx
  export default async function ReviewsPage({ searchParams }) {
    const page = parsePageParam(searchParams.page);
    const pageSize = PAGE_SIZE;
    const { reviews, pagination } = await getReviews(pageSize, page);
    // Fetch and render reviews based on the current page
  }
  ```

#### Fetching the Correct Reviews

**Step 4: Implement Data Fetching Logic**

This step involves modifying the data fetching logic to ensure the correct set of reviews is displayed for each page.

* **Modify `getReviews` Function**: This function now accepts `pageSize` and `page` parameters. It fetches the appropriate set of reviews and returns both the reviews and pagination metadata.

  ```javascript
  //lib/reviews.js
  export async function getReviews(pageSize, page) {
    const { data, meta } = await fetchReviews({
      fields: ['slug', 'title', 'subtitle', 'publishedAt'],
      populate: { image: { fields: ['url'] } },
      sort: ['publishedAt:desc'],
      pagination: { pageSize, page },
    });
    return {
      reviews: data.map(toReview),
      pagination: meta.pagination,
    };
  }
  ```

  * **Data**: Contains the actual reviews.
  * **Meta**: Includes pagination information such as the current page and total page count.
* **Integrate in `ReviewsPage`**: This component fetches reviews based on the current page and renders them.

  ```jsx
  //app/reviews/page.jsx
  export default async function ReviewsPage({ searchParams }) {
    const page = parsePageParam(searchParams.page);
    const pageSize = PAGE_SIZE;
    const { reviews, pagination } = await getReviews(pageSize, page);
    
    return (
      <>
        <Heading>Reviews</Heading>
        <div className="flex gap-2 pb-3">
          {pagination.page > 1 && (
            <Link href={`/reviews?page=${pagination.page - 1}`}>&lt; Prev</Link>
          )}
          <span>Page {pagination.page} of {pagination.pageCount}</span>
          {pagination.page < pagination.pageCount && (
            <Link href={`/reviews?page=${pagination.page + 1}`}>Next &gt;</Link>
          )}
        </div>
        {/* ... rest of your component ... */}
      </>
    );
  }
  ```

#### Conclusion

By implementing pagination, users can efficiently navigate through different sets of reviews. The combination of UI, URL parameter handling, and data fetching logic ensures that the correct reviews are displayed for each page. This setup also includes basic error handling, such as ensuring that invalid page numbers default to 1, and only displaying navigation links when appropriate. Future enhancements could include disabling links when on the first or last page to prevent unnecessary requests.
