0
0
NextjsHow-ToBeginner · 4 min read

How to Create Pagination in Next.js: Simple Guide

To create pagination in Next.js, use dynamic routes with query parameters or path segments to track the current page, and fetch data accordingly using getServerSideProps or getStaticProps. Render page links that update the URL to load different pages smoothly.
📐

Syntax

Pagination in Next.js typically involves these parts:

  • Dynamic Routes: Use file names like [page].js to capture page numbers.
  • Data Fetching: Use getServerSideProps or getStaticProps to fetch data for the current page.
  • Navigation Links: Render links or buttons that change the page number in the URL.
javascript
export async function getServerSideProps(context) {
  const page = context.params.page || '1';
  const data = await fetchDataForPage(page);
  return { props: { data, page } };
}

export default function Page({ data, page }) {
  return (
    <>
      <div>Showing data for page {page}</div>
      {/* Render data here */}
      <nav>
        <a href={`/page/${parseInt(page) - 1}`}>Previous</a>
        <a href={`/page/${parseInt(page) + 1}`}>Next</a>
      </nav>
    </>
  );
}
💻

Example

This example shows a simple Next.js page that uses dynamic routing and server-side data fetching to paginate a list of items. It fetches 10 items per page and provides Previous and Next links.

javascript
import { useRouter } from 'next/router';

const ITEMS_PER_PAGE = 10;

async function fetchItems(page) {
  // Simulate fetching data from an API
  const allItems = Array.from({ length: 100 }, (_, i) => `Item ${i + 1}`);
  const start = (page - 1) * ITEMS_PER_PAGE;
  return allItems.slice(start, start + ITEMS_PER_PAGE);
}

export async function getServerSideProps(context) {
  const page = parseInt(context.params.page) || 1;
  const items = await fetchItems(page);
  return { props: { items, page } };
}

export default function PaginatedPage({ items, page }) {
  const router = useRouter();

  const goToPage = (newPage) => {
    if (newPage < 1) return;
    router.push(`/page/${newPage}`);
  };

  return (
    <main>
      <h1>Page {page}</h1>
      <ul>
        {items.map(item => <li key={item}>{item}</li>)}
      </ul>
      <nav>
        <button onClick={() => goToPage(page - 1)} disabled={page === 1} aria-label="Previous page">Previous</button>
        <button onClick={() => goToPage(page + 1)} aria-label="Next page">Next</button>
      </nav>
    </main>
  );
}
Output
Page 1 - Item 1 - Item 2 - Item 3 - Item 4 - Item 5 - Item 6 - Item 7 - Item 8 - Item 9 - Item 10 [Previous (disabled)] [Next]
⚠️

Common Pitfalls

Common mistakes when creating pagination in Next.js include:

  • Not handling the first or last page properly, causing navigation to invalid pages.
  • Fetching all data at once instead of only the current page's data, which hurts performance.
  • Using client-side routing without updating the URL, which breaks bookmarking and sharing.
  • Not disabling navigation buttons when on the first or last page, confusing users.
javascript
/* Wrong: No check for page bounds and fetches all data */
export async function getServerSideProps() {
  const data = await fetchAllData(); // inefficient
  return { props: { data } };
}

/* Right: Fetch only current page data and check bounds */
export async function getServerSideProps(context) {
  const page = Math.max(1, parseInt(context.params.page) || 1);
  const data = await fetchDataForPage(page);
  return { props: { data, page } };
}
📊

Quick Reference

  • Use [page].js in pages folder for dynamic page numbers.
  • Fetch data for the current page in getServerSideProps or getStaticProps.
  • Render navigation links or buttons that update the URL to the new page.
  • Disable or hide navigation controls when no more pages exist.
  • Use router.push for client-side navigation to keep the app fast.

Key Takeaways

Use dynamic routes like [page].js to capture the current page number in Next.js.
Fetch only the data needed for the current page using getServerSideProps or getStaticProps.
Render navigation controls that update the URL to enable smooth page changes and bookmarking.
Always handle edge cases like first and last pages to avoid broken navigation.
Use client-side navigation with router.push for better user experience.