---
title: Pagination
slug: experience/pagination
docTags: 
createdAt: 2026-01-08T13:50:32.970Z
---

In Experience, lists use **infinite scrolling by default**.
When the user scrolls to the bottom of the list, more data is automatically loaded until the end of the dataset is reached.

By default:

- Each load adds **24 items**&#x20;
- This value can be overridden using the **Batch Size** field in the data source configuration.&#x20;

If you want to **disable infinite scrolling**, you must define a **limit** in the data source.
&#x20;Once a limit is set, the list will **not auto-load more items** when scrolling.

This document covers:

1. Default infinite scrolling behavior&#x20;
2. Manual pagination (next/previous buttons, no infinite scrolling)&#x20;

## 1. Infinite Scrolling (Default Behavior)

### Behavior

- Data loads automatically when scrolling to the bottom&#x20;
- Each batch loads **24 elements** by default&#x20;
- Continues until all data is loaded&#x20;

### Configuration

In the **List Component → Datasource settings**:

- ✅ Data source enabled&#x20;
- 🔢 **Batch Size** (optional): override default 24 items per load&#x20;
- ❌ Do **not** set a limit → infinite scrolling remains active&#x20;

![](https://api.archbee.com/api/optimize/ygR6KtT9QI_R0u3uKTJsm/NaDyrA_9UKQnsWnBiS3w--20260119-103049.png)

```json
{
  "content": {
    "tag": "div",
    "type": "html",
    "content": "[]"
  },
  "dataSource": {
    "type": "content",
    "batchSize": 24
  },
  "type": "list"
}
```

## 2. Manual Pagination (No Infinite Scrolling) ( PXP 5.1.0 )

### Goal

- Display a fixed number of items (e.g. 10)&#x20;
- No automatic loading on scroll&#x20;
- Navigation only via **Next** and **Previous** buttons&#x20;

### Concept

Pagination is controlled using:

- A **limit** on the datasource&#x20;
- A **cursor/offset** stored in context&#x20;
- Buttons that modify the offset via navigation params&#x20;

## Required Components

To implement manual pagination, configure **3 components**:

1. List Component&#x20;
2. Previous Button&#x20;
3. Next Button&#x20;

## 2.1 List Component Configuration

### Step 1 - Enable Data Source

In **List Component → Datasource**:

- ✅ Enable datasource&#x20;
- Choose the datasource type as needed&#x20;

### Step 2 - Limit (Page Size)

Set:

- **Limit = 10** (or any page size you want)&#x20;

This ensures:

- Only 10 elements are shown&#x20;
- Infinite scrolling is disabled&#x20;

### Step 3 - Cursor / Offset

Add **Cursor field**:

- **Value:** $context.offset&#x20;
- **Condition:** $context.offset IS SET&#x20;

This allows the data source to know:

- From which position should it load data&#x20;

:::BlockQuote
💡 You may name the parameter something else (e.g. pageOffset),
&#x20;but then all references must use $context.pageOffset.
:::

![](https://api.archbee.com/api/optimize/ygR6KtT9QI_R0u3uKTJsm/6ysahi1o04cpmiualz2As-20260108-154201.png)

```json
{
  "content": {
    "tag": "div",
    "type": "html",
    "content": "$context.content.name"
  },
  "dataSource": {
    "type": "content",
    "limit": 10,
    "fetchOptions": {
      "totalCount": true
    },
    "contextKey": "contents",
    "cursor": {
      "value": "$context.offset",
      "condition": {
        "value": "$context.offset",
        "operation": "SET"
      }
    }
  },
  "type": "list"
}
```

## 2.2 "Previous" Button Configuration

### Visibility Condition

Button is shown only when:

:::BlockQuote
$context.offset > 0
:::

This prevents showing "Previous" on the first page.

### Tap Action

Set **Tap Action → Navigation**:

- Path: **current path**&#x20;
- Params:&#x20;
  - Key: offset&#x20;
  - Value:&#x20;

:::BlockQuote
$functions.add($context.offset, -10)
:::

This:

- Decreases offset by page size&#x20;
- Loads previous set of elements&#x20;

![](https://api.archbee.com/api/optimize/ygR6KtT9QI_R0u3uKTJsm/Cs35wcgKklPbah0nsgTzk-20260108-154305.png)

```json
{
  "tag": "div",
  "type": "html",
  "content": "prev page",
  "tap": {
    "type": "navigate",
    "params": {
      "offset": "$functions.add($context.offset, -10)"
    }
  },
  "condition": {
    "compareValue": "$functions.add($context.offset, 0)",
    "value": "0",
    "negated": true
  }
}
```

## 2.3 Next Button Configuration

### Visibility Condition

Button is shown only when:

:::BlockQuote
$context.contents.hasNextPage == true
:::

Where:

- contents = datasource result&#x20;
- hasNextPage indicates more data is available&#x20;

### Tap Action

Set **Tap Action → Navigation**:

- Path: **current path**&#x20;
- Params:&#x20;
  - Key: offset&#x20;
  - Value:&#x20;

:::BlockQuote
$functions.add($context.offset, 10)
:::

This:

- Increases offset by page size&#x20;
- Loads next set of elements&#x20;

![](https://api.archbee.com/api/optimize/ygR6KtT9QI_R0u3uKTJsm/x7cIaOJ48W_w9LGwh7FmA-20260108-154734.png)

```json
{
  "tag": "div",
  "type": "html",
  "content": "next page",
  "tap": {
    "type": "navigate",
    "params": {
      "offset": "$functions.add($context.offset, 10)"
    }
  },
  "condition": {
    "operation": "EQUALS",
    "compareValue": "true",
    "value": "$context.contents.hasNextPage"
  }
}
```

## 2.4 functions

add **add** and **toJson**  functions to **custom.server.js&#x20;**

```javascript
window.$functions = {
    toJson: (val) => JSON.stringify(val, null, 2),
    add: (val, plus) => parseInt(val ?? '0') + plus
}
```

Summary

| Feature             | Infinite Scrolling | Manual Pagination |
| ------------------- | ------------------ | ----------------- |
| Auto-load on scroll | ✅ Yes              | ❌ No              |
| Uses limit          | ❌ No               | ✅ Yes             |
| Uses offset/cursor  | ❌ No               | ✅ Yes             |
| Requires buttons    | ❌ No               | ✅ Next / Prev     |
| Page size control   | Batch Size         | Limit             |

