Fruitful Docs
GuidesCapture

Handle scroll and pagination

Capture feeds that load more entries as you scroll, virtualize their items, or paginate.

A snapshot captures what is in the DOM. Feeds that load on scroll or split across pages need a scroll strategy on the route so the snapshot holds every entry the package should see.

Pick a kind

"scroll": { "kind": "finite", "maxAttempts": 1 }
kindWhat it doesNeeds
finiteScrolls to the bottom a bounded number of timesnothing else
infiniteScrolls container until item count stops growingcontainer, item
stitchingLike infinite, and keeps virtualized items that leave the DOMcontainer, item, dedupeAttribute
paginateFollows next and stitches each page's items into one snapshotcontainer, item, next

The registry enforces the requirements: container and item for anything but finite, next for paginate.

Infinite scroll

"scroll": {
  "kind": "infinite",
  "container": "main",
  "item": "div[data-id]",
  "minItems": 40,
  "maxAttempts": 12,
  "delayMs": 800,
  "itemGrowthTimeoutMs": 6000
}

minItems stops early once enough entries are present; maxAttempts and itemGrowthTimeoutMs bound the wait. Choose item to be the same element your binding's entry selector matches, so what is counted is what is extracted.

Virtualized lists

Some feeds remove items from the DOM as you scroll past them. stitching keeps a copy of each item keyed by dedupeAttribute so the snapshot contains every item seen:

"scroll": { "kind": "stitching", "container": "main", "item": "[data-urn]", "dedupeAttribute": "data-urn" }

Paginated archives

"scroll": { "kind": "paginate", "container": "main", "item": "article", "next": "a[rel=next]", "maxPages": 5 }

The next link is followed until it is absent, minItems is reached, or maxPages (default 5, first page included) is hit. Each page's items are stitched into one snapshot, so the binding and transform see one list.

Readiness comes first

Scrolling starts only after the route's ready selector is satisfied. Set it to your entry selector so an empty or still-loading page does not scroll a placeholder:

"ready": { "selector": "tr.submission" }

Reference: scroll, readiness.

On this page