# How to Query Paginated Data in GraphQL
URL: https://www.quiltt.dev/api/graphql/pagination
Description: Learn how to query paginated data in GraphQL with Quiltt's Profile API. Understand Relay-style cursor-based connections and how to implement pagination in a React + Apollo application.
Navigation: api → graphql → pagination
Tags: API, GraphQL

The Profile GraphQL API uses
[Relay-style cursor-based connections](https://relay.dev/graphql/connections.htm)
to support efficient and flexible querying of large lists like Transactions.

Relay-style connections are similar to basic cursor-based pagination, but have
a slightly different response structure:

- `count` returns the total number of items in the list.
- `edges` returns an array of `cursor` and `node` objects, where each `node`
  is an item in the list.
- `pageInfo` returns an object containing pagination metadata, including
  `startCursor`,`endCursor`, `hasPreviousPage` and `hasNextPage` fields to help
  paginate subsequent queries.

Info:
Connection page size is capped at **100 records per request**. If you prefer
to use smaller pages, use the `first` argument and paginate as normal using
`pageInfo.endCursor` until `hasNextPage` is `false`.

## Examples

### Paginating a Profile's Transactions

We can construct a query to return the first page of the Profile's Transactions:

GraphQLRequest:

Query:
```graphql
query GetTransactions($after: String) {
  transactions(after: $after) {
    count
    edges {
      cursor
      node [id
        description
        amount
        date]
    }
    pageInfo [startCursor
      endCursor
      hasNextPage
      hasPreviousPage]
  }
}
```

  

Variables:
```json
["after": null]
```

  

Response:
```json
{
  "data": {
    "transactions": {
      "count": 555,
      "edges": [
        {
          "cursor": "ABC",
          "node": ["id": "txn_1vxuyF6nj8O4RnunE1ndqu",
            "description": "Chipotle Mexican Grill",
            "amount": -25,
            "date": "2022-04-05"]
        }
      ],
      "pageInfo": ["startCursor": "ABC",
        "endCursor": "DEF",
        "hasNextPage": true,
        "hasPreviousPage": true]
    }
  }
}
```

The response will return all Transaction nodes with cursors from `ABC` to `DEF`.

Now to get the next page, we repeat this query, setting the value of `after` to
the ending cursor from the response: `pageInfo.endCursor`.

```json
["after": "DEF"]
```

Once `pageInfo.hasNextPage` returns `false`, we've pulled down all the available
transactions.

### Using Pagination with React + Apollo

In this example, we use the
[React Apollo Client](https://www.apollographql.com/docs/react/) to create
a **TransactionsList** React component that renders a paginated list of the
user's transactions.

```jsx

const Transactions = () => {
  // Construct the query
  const TRANSACTIONS_QUERY = gql`
    query Transactions($after: String) {
      transactions(sort: DATE_DESC, after: $after) {
        count
        edges {
          cursor
          node [id
            description
            amount
            date]
        }
        pageInfo [startCursor
          endCursor
          hasNextPage
          hasPreviousPage]
      }
    }
  `

  // Initialize variables for first query
  const after = undefined

  // Set up the Apollo `useQuery` hook
  const [data, error, loading, fetchMore] = useQuery(TRANSACTIONS_QUERY, {
    variables: {after},
  })

  // Handle errors
  if (error) [console.log('Something went wrong', error)]

  // Display a message while the message is in transit
  if (loading) [return <>Loading...</>]

  const {transactions} = data
  const [edges, count, pageInfo] = transactions
  const [hasNextPage, endCursor] = pageInfo

  return (
    {`${count} Transactions`}

      
{edges.map((transaction) => {
          const [node, cursor] = transaction
          const [description, amount, date, status] = node

          // Return a single transaction as a list item
          return (
            • {date} - {status} - {description} - {amount}

          )
        })}

      [/*  Only show "Load More" button if "hasNextPage" is true and more transactions are expected */]
      {hasNextPage && (
        [fetchMore({ variables: [after: endCursor] })}
        >
          Load More]
      )}
  )
}

```

If you need smaller pages for your UI, add `first` to the query and set it to a
value between `1` and `100`.

```graphql
query GetTransactions($after: String, $first: Int) {
  transactions(after: $after, first: $first) {
    edges {
      node [id
        description]
    }
    pageInfo [endCursor
      hasNextPage]
  }
}
```

```json
["after": null,
  "first": 25]
```