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 }| kind | What it does | Needs |
|---|---|---|
finite | Scrolls to the bottom a bounded number of times | nothing else |
infinite | Scrolls container until item count stops growing | container, item |
stitching | Like infinite, and keeps virtualized items that leave the DOM | container, item, dedupeAttribute |
paginate | Follows next and stitches each page's items into one snapshot | container, 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" }