DEV Community

Cover image for How to Test Cursor-Based Pagination & Infinite Scroll in React Without a Backend
Nilesh Kumar
Nilesh Kumar

Posted on Originally published at playground.nileslabs.com

How to Test Cursor-Based Pagination & Infinite Scroll in React Without a Backend

Standard offset-based pagination (?page=2&limit=10) works fine for simple tables, but for modern infinite scroll feeds (Twitter, Instagram, Reddit style), offset pagination fails because:

  • New items inserted at the top shift the entire list, causing duplicate items or skipped entries when scrolling down.
  • Database OFFSET queries degrade severely on large datasets.

Modern production APIs use Cursor-Based Pagination (?cursor=<base64>&limit=10), returning a pointer to the last item seen (nextCursor) and a boolean hasMore flag.

Playground API now provides native Cursor-Based Pagination across all endpoints!


1. The Cursor Endpoint Contract

Make a request with cursor and limit:

curl "https://playground.nileslabs.com/posts?cursor=eyJpZCI6MTB9&limit=10"
Enter fullscreen mode Exit fullscreen mode

JSON Response:

{
  "data": [
    { "id": 11, "title": "Next Post Title", "body": "..." },
    { "id": 12, "title": "Another Post", "body": "..." }
  ],
  "pagination": {
    "nextCursor": "eyJpZCI6MjB9",
    "hasMore": true,
    "total": 100
  }
}
Enter fullscreen mode Exit fullscreen mode

When reaching the end of the collection, hasMore returns false and nextCursor returns null.


2. Integrating with TanStack React Query (useInfiniteQuery)

import { useInfiniteQuery } from '@tanstack/react-query';

async function fetchPosts({ pageParam = null }: { pageParam?: string | null }) {
  const url = pageParam
    ? `https://playground.nileslabs.com/posts?cursor=${pageParam}&limit=10`
    : 'https://playground.nileslabs.com/posts?limit=10';

  const res = await fetch(url);
  return res.json();
}

export function InfiniteFeed() {
  const {
    data,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
  } = useInfiniteQuery({
    queryKey: ['infinite-posts'],
    queryFn: fetchPosts,
    getNextPageParam: (lastPage) => lastPage.pagination.nextCursor,
    initialPageParam: null,
  });

  return (
    <div>
      {data?.pages.map((page, i) => (
        <div key={i}>
          {page.data.map((post: any) => (
            <div key={post.id} className="post-card">
              <h4>{post.title}</h4>
            </div>
          ))}
        </div>
      ))}

      {hasNextPage && (
        <button onClick={() => fetchNextPage()} disabled={isFetchingNextPage}>
          {isFetchingNextPage ? 'Loading more...' : 'Load More'}
        </button>
      )}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

3. Interactive Pagination Studio

Explore cursor tokens, page parameters, and infinite scrolling in the documentation:
šŸ‘‰ https://playground.nileslabs.com/docs/pagination


Conclusion

Test real infinite scroll feeds and TanStack Query caching seamlessly with Playground API!

Top comments (0)