InfiniteScroll
Viewport-triggered pagination wrapper with loading and end-of-list states. Supports automatic sentinel loading or an accessible manual load-more button fallback.
Best for
Import
import { InfiniteScroll } from "@enadhq/enad-react-sdk/client/storefront"When to use it
Use InfiniteScroll when a listing page should progressively load more content as the visitor scrolls rather than using numbered pagination. It works well for product grids, editorial feeds, and search results where browsing momentum matters more than jumping to a specific page.
If the visitor needs to jump to specific pages or the dataset is very large, use Pagination instead. If the content set is small and fits on one page, neither is needed.
Composition notes
InfiniteScroll wraps your list content as children:
childrenis the rendered list (a product grid, editorial feed, etc.).onLoadMorefires when the sentinel reaches the viewport (automatic mode) or when the button is clicked (manual mode).hasMoretells the component whether more content is available. When false, the end indicator shows instead.loadingshows the loading indicator while the next page is being fetched.showLoadMoreButtonswitches from automatic viewport-triggered loading to a manual button. Use this for accessibility or when automatic loading would interfere with footer access.thresholdcontrols how early the sentinel triggers relative to the viewport edge (IntersectionObserver rootMargin).loadingIndicatorandendIndicatorare ReactNode slots for custom loading and end-of-list UI.
Behavior and theming guidance
The automatic sentinel uses IntersectionObserver with a configurable threshold (default "200px"). This means loading triggers before the visitor actually reaches the bottom, creating a seamless experience.
The manual load-more button renders centered below the content with the loadMoreLabel text. It disables during loading to prevent double-fetches.
When hasMore becomes false, the endIndicator renders in place of the sentinel or button. Use a short message like "All products loaded" or a subtle visual divider.
Examples
Live examples you can edit directly in the sandbox.
Automatic loading
Use the sentinel-based default when you want additional content to appear as the customer scrolls.
Manual load more button
Switch to an explicit button when you want progressive loading without automatic viewport triggers.
Component Sets
Preview the first example across the available component-set presets to compare tone, spacing, and structural defaults.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| onLoadMore | () => void | — | No description yet. |
| hasMore | boolean | — | No description yet. |
| loading | boolean | false | No description yet. |
| threshold | string | 200px | IntersectionObserver rootMargin |
| showLoadMoreButton | boolean | false | Fallback "Load more" button for accessibility |
| loadMoreLabel | string | Load more | No description yet. |
| loadingIndicator | string | — | Loading indicator slot |
| endIndicator | string | — | End-of-list indicator slot |
| className | string | — | No description yet. |