useElementVisibility
React Element Hooks that tracks the visibility of an element within the viewport. A wrapper of useIntersectionObserver
useElementVisibility provides a simple boolean indicating whether a DOM element is currently visible within the viewport. It is built on top of useIntersectionObserver and abstracts away the complexity of the Intersection Observer API. It returns a tuple of [isVisible, stop] where stop is a function to disconnect the observer.
When to Use
- Triggering animations or lazy-loading content when an element scrolls into view
- Implementing “read receipt” or “seen” tracking for feed items or notifications
- Conditionally rendering or pausing resource-intensive components when they are off-screen
Notes
- SSR-safe: Returns
falseduring server-side rendering since no DOM is available. - Customizable: Accepts standard
IntersectionObserverInitoptions (root,rootMargin,threshold) for fine-grained control over when visibility triggers. - See also
useIntersectionObserverfor full access toIntersectionObserverEntrydata, anduseDocumentVisibilityfor page-level (tab) visibility.
Usage
Live Editor
function Demo() { const ref = useRef<HTMLDivElement>(null); const [visible, stop] = useElementVisibility(ref); return ( <div> <p>Info on the right bottom corner</p> <div ref={ref} style={{ borderWidth: 2, borderStyle: "solid", padding: "1rem", }} > Target Element (scroll down) </div> <button onClick={() => { stop(); }} > Stop </button> <div style={{ borderWidth: 2, borderStyle: "solid", padding: "1rem", position: "fixed", bottom: 0, right: 0, zIndex: 100, }} > Element {visible ? "inside" : "outside"} the viewport </div> </div> ); };
Result
API
useElementVisibility
Returns
readonly [boolean, () => void]: A tuple with the following elements:
- is the current element visible.
- stop observer listening function.
Arguments
| Argument | Description | Type | DefaultValue |
|---|---|---|---|
| target | dom element | BasicTarget<HTMLElement | SVGElement> (Required) | - |
| options | options passed to intersectionObserver | IntersectionObserverInit | undefined | - |
BasicTarget
export type BasicTarget<T extends TargetType = Element> = (() => TargetValue<T>) | TargetValue<T> | MutableRefObject<TargetValue<T>>;
TargetValue
type TargetValue<T> = T | undefined | null;
TargetType
type TargetType = HTMLElement | Element | Window | Document | EventTarget;