0
0
GraphqlHow-ToBeginner · 4 min read

How to Implement Infinite Scroll with GraphQL Efficiently

To implement infinite scroll with GraphQL, use cursor-based pagination by requesting a limited number of items with first and a after cursor. Fetch more data by passing the last item's cursor to after as the user scrolls, enabling smooth incremental loading.
📐

Syntax

Infinite scroll in GraphQL typically uses cursor-based pagination with these parts:

  • first: Number of items to fetch.
  • after: Cursor pointing to the last fetched item.
  • edges: List of items with cursors.
  • pageInfo: Contains hasNextPage and endCursor to control loading.
graphql
query GetItems($first: Int!, $after: String) {
  items(first: $first, after: $after) {
    edges {
      node {
        id
        name
      }
      cursor
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
💻

Example

This example shows a GraphQL query fetching 5 items at a time using cursor-based pagination. The client uses endCursor to load the next batch when scrolling.

graphql
query FetchProducts($first: Int!, $after: String) {
  products(first: $first, after: $after) {
    edges {
      node {
        id
        title
      }
      cursor
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

# Variables for first fetch
{
  "first": 5,
  "after": null
}

# Variables for next fetch after scrolling
{
  "first": 5,
  "after": "cursor-from-last-item"
}
Output
{ "data": { "products": { "edges": [ {"node": {"id": "1", "title": "Product 1"}, "cursor": "cursor1"}, {"node": {"id": "2", "title": "Product 2"}, "cursor": "cursor2"}, {"node": {"id": "3", "title": "Product 3"}, "cursor": "cursor3"}, {"node": {"id": "4", "title": "Product 4"}, "cursor": "cursor4"}, {"node": {"id": "5", "title": "Product 5"}, "cursor": "cursor5"} ], "pageInfo": { "hasNextPage": true, "endCursor": "cursor5" } } } }
⚠️

Common Pitfalls

Common mistakes when implementing infinite scroll with GraphQL include:

  • Using offset-based pagination instead of cursor-based, which can cause duplicates or missing items when data changes.
  • Not checking hasNextPage before fetching more data, leading to unnecessary requests.
  • Failing to update the after cursor with the latest endCursor, causing repeated data.
graphql
query WrongPagination {
  items(offset: 0, limit: 5) {
    id
    name
  }
}

# Correct approach uses cursor-based pagination:
query CorrectPagination($first: Int!, $after: String) {
  items(first: $first, after: $after) {
    edges {
      node {
        id
        name
      }
      cursor
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
📊

Quick Reference

TermDescription
firstNumber of items to fetch per request
afterCursor to start fetching after
edgesList of items with their cursors
nodeThe actual item data
pageInfoPagination info including hasNextPage and endCursor
hasNextPageBoolean indicating if more items exist
endCursorCursor of the last item fetched

Key Takeaways

Use cursor-based pagination with first and after for reliable infinite scroll.
Always check hasNextPage before loading more data to avoid extra requests.
Update the after cursor with endCursor from the last fetch to get new items.
Avoid offset-based pagination as it can cause data inconsistencies during scrolling.
Structure your query to return edges and pageInfo for smooth incremental loading.