Implement pagination on the server

I'm currently setting a URL parameter with the value of the current page number. I fetch the items by page number on page.tsx and pass them to my client table component. Is this the best way to do this? More details: I'm using Prisma Here's and example of what I'm doing:
// page.tsx

const LIMIT = 10;

async function fetchItems(page: number) {
const items = prisma.item.findMany(...);
const itemsCount = prisma.item.count();
const pagesCount = Math.ceil(itemsCount / LIMIT);
const hasNextPage = page < pagesCount - 1;
const hasPreviousPage = page > 0;
return { items, hasNextPage, hasPreviousPage };
}

export default async function Page({searchParams}) {
const pageParam = searchParams.page;
const page = pageParam ? parseInt(pageParam) : 0;
const { items, hasNextPage, hasPreviousPage } = await fetchItems(page);

return (
<>
<Table ... />
{/* disable links when there's no page */}
<Link href={`/...?page=${page - 1}`}>Previous</Link>
<Link href={`/...?page=${page + 1}`}>Next</Link>
</>
)
}
// page.tsx

const LIMIT = 10;

async function fetchItems(page: number) {
const items = prisma.item.findMany(...);
const itemsCount = prisma.item.count();
const pagesCount = Math.ceil(itemsCount / LIMIT);
const hasNextPage = page < pagesCount - 1;
const hasPreviousPage = page > 0;
return { items, hasNextPage, hasPreviousPage };
}

export default async function Page({searchParams}) {
const pageParam = searchParams.page;
const page = pageParam ? parseInt(pageParam) : 0;
const { items, hasNextPage, hasPreviousPage } = await fetchItems(page);

return (
<>
<Table ... />
{/* disable links when there's no page */}
<Link href={`/...?page=${page - 1}`}>Previous</Link>
<Link href={`/...?page=${page + 1}`}>Next</Link>
</>
)
}
Is the navigation correct? I'm not sure how to prevent people from changing the URL param and go to pages that don't exist. At least I'm looking for the current best practice. This would be unnecessary if I could use tRPC in /app. If there's a workaround with that I would appreciate it.
3 Replies
ahkhanjani
ahkhanjani13mo ago
Anything?
Sybatron
Sybatron13mo ago
This would be quiet slow if you don't use prisma's cursor pagination i think https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination
Prisma
Pagination (Reference)
Prisma Client supports both offset pagination and cursor-based pagination. Learn more about the pros and cons of different pagination approaches and how to implement them.
Sybatron
Sybatron13mo ago
if you are just skipping X items and taking 10 as it will go trough all items you skip before getting these 10