Build server-side pagination using the Next.js App Router

Server-side pagination is crucial for SEO performance, as web crawlers cannot index an infinite scroll page or click on a "load more" button. It also enhances the user experience by making it easy to share a specific page with others. Let's build this!

The ‘UsersPage’ component

The UsersPage component is a React Server Component that receives the searchParams prop provided by Next.js. Its responsibility is to fetch users, create the required pagination data, and render the list of users.

import { getUsers } from '@server/data/user';
import Pagination from '@components/Pagination';

type Props = {
  searchParams: { page: number };
};

export default async function UsersPage({ searchParams }: Props) {
  const allUsers = await getUsers();

  const usersPerPage = 10;
  const page = searchParams.page || 1;
  const start = (+page - 1) * usersPerPage;
  const end = start + usersPerPage;

  const users = allUsers.slice(start, end);
  const totalPages = Math.ceil(allUsers.length / usersPerPage);

  return (
    <main>
      <section>
        {users.length > 0 ? (
          <>
            {users.map((user) => (
              <p key={user.id}>{user.name}</p>
            ))}
          </>
        ) : (
          <p>Whoops! No user found 🫤</p>
        )}
      </section>
      <Pagination totalPages={totalPages} />
    </main>
  );
}

Within this component, we fetch the users by calling the getUsers function. Next, we create a usersPerPage variable and set it to 10. After that, we create a page variable, setting it to the value of the page property in searchParams if it exists; otherwise, it defaults to 1.

After that, we calculate the start and end indices, which represent the range of users to display on the current page. To get the start index, we subtract 1 from the page variable and multiply the result by usersPerPage. To get the end index, we add usersPerPage to start. For example, on the second page, the start index is 10 ((2 - 1) * 10), and the end index is 20 (10 + 10).

Next, we create a users variable by slicing the allUsers array using the start and end indices. We also create a totalPages variable by dividing the length of the allUsers array by usersPerPage and wrapping the result in Math.ceil to round up. Finally, we render the list of users using JSX.

The ‘Pagination’ component

The Pagination component is a React Client Component that receives the totalPages prop. It provides an interface to navigate between pages and displays the current page number and the total number of pages.

'use client';

import { useSearchParams } from 'next/navigation';
import Link from 'next/link';

type Props = {
  totalPages: number;
};

export default function Pagination({ totalPages }: Props) {
  const searchParams = useSearchParams();
  const page = searchParams.get('page') || 1;

  return (
    <section>
      <Link rel='prev' href={`/users/?page=${+page > 1 ? +page - 1 : +page}`}>
        Previous
      </Link>
      <p>
        {page}/{totalPages}
      </p>
      <Link
        rel='next'
        href={`/users/?page=${+page < totalPages ? +page + 1 : +page}`}
      >
        Next
      </Link>
    </section>
  );
}

Within the component, we use the useSearchParams hook provided by Next.js to retrieve the searchParams. After that, we create a page variable, setting it to the value of the page property in searchParams if it exists; otherwise, it defaults to 1.

Finally, we return JSX to navigate between pages and display the current page number and the total number of pages. With this setup, navigating to a previous or next page updates the searchParams in the UsersPage, causing the page to re-render with the updated paginated data.

That's it! You now know how to create server-side pagination that improves your application's SEO performance and enhances user experience by allowing users to share a specific page with others. I hope you've learned something valuable from this article. Feel free to share it with others who might be interested in implementing server-side pagination using the Next.js App Router.

Share this article with your friends

Copy URL

Elevate your JavaScript and freelance journey

Supercharge your JavaScript skills and freelance career. Subscribe now for expert tips and insights!