Skip to Content
HooksuseIntersectionObserver

useIntersectionObserver

useIntersectionObserver is the lower-level visibility hook in react-rsc-kit.

It supports both an external ref and the callback ref returned by the hook.

Live Example

Scrollable visibility tracker

This demo uses the real hook against a scroll container so you can see the observer state update live.

Scroll inside the demo area. The observed card updates when it enters the tracked viewport.

Scroll down
Outside the viewportIntersection ratio: 0.00Seen at least once: false

Import

import { useIntersectionObserver } from "react-rsc-kit/client";

Signature

const result = useIntersectionObserver<T>(options?);

Parameters

NameTypeDefaultDescription
refReact.RefObject<T | null> | nullundefinedOptional external ref for the target element.
rootElement | Document | React.RefObject<Element | null> | nullnullCustom observer root.
rootMarginstring"0px"Root margin passed to the observer.
thresholdnumber | number[]0Visibility threshold or thresholds.
freezeOnceVisiblebooleanfalseStops observing after the first visible intersection.
triggerOncebooleanfalseLegacy compatibility alias for freezeOnceVisible.
disabledbooleanfalsePrevents observation without unmounting the hook.
initialIsIntersectingbooleanfalseInitial visibility state before the first observer update.
fallbackInViewbooleanundefinedFallback visibility state when IntersectionObserver is unavailable.
onChange(entry, observer) => voidundefinedRuns on each observer update.

Returns

KeyDescription
refCallback ref for the target element.
entryLatest IntersectionObserverEntry or null.
isIntersectingWhether the target is currently visible.
hasIntersectedWhether the target has ever intersected in the current lifecycle.
intersectionRatioLatest ratio, defaults to 0.
boundingClientRectLatest bounding rect or null.
intersectionRectLatest intersection rect or null.
rootBoundsLatest root bounds or null.
timeTimestamp from the latest entry.
targetCurrent observed node or null.
isSupportedWhether IntersectionObserver exists in the current environment.
disconnectManually disconnects the active observer.

Usage

"use client"; import { useIntersectionObserver } from "react-rsc-kit/client"; export function LazyImage({ src }: { src: string }) { const { ref, isIntersecting } = useIntersectionObserver<HTMLDivElement>({ threshold: 0.25, freezeOnceVisible: true, }); return <div ref={ref}>{isIntersecting ? <img src={src} alt="" /> : null}</div>; }

Notes

  • freezeOnceVisible is the preferred option name.
  • Use ref when the target node is created inside the same component.
  • For a simpler boolean-only API, use useOnScreen.
Last updated on