Theme Playground

Commerce

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

product gridseditorial feedssearch results with progressive loading

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:

  • children is the rendered list (a product grid, editorial feed, etc.).
  • onLoadMore fires when the sentinel reaches the viewport (automatic mode) or when the button is clicked (manual mode).
  • hasMore tells the component whether more content is available. When false, the end indicator shows instead.
  • loading shows the loading indicator while the next page is being fetched.
  • showLoadMoreButton switches from automatic viewport-triggered loading to a manual button. Use this for accessibility or when automatic loading would interfere with footer access.
  • threshold controls how early the sentinel triggers relative to the viewport edge (IntersectionObserver rootMargin).
  • loadingIndicator and endIndicator are 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.

2 examples

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

PropTypeDefaultDescription
onLoadMore() => void
No description yet.
hasMoreboolean
No description yet.
loadingbooleanfalse
No description yet.
thresholdstring200px
IntersectionObserver rootMargin
showLoadMoreButtonbooleanfalse
Fallback "Load more" button for accessibility
loadMoreLabelstringLoad more
No description yet.
loadingIndicatorstring
Loading indicator slot
endIndicatorstring
End-of-list indicator slot
classNamestring
No description yet.