useIntersectionObserver
Reactive wrapper around the IntersectionObserver API.
Observes one or more elements for intersection changes with pause/resume/stop support.
Targets can be Ref$, MaybeElement, or a plain Element.
isIntersecting: false
rootMargin:
↓ scroll down
target element
import { useRef$, useIntersectionObserver } from "@usels/core";
function Component() { const el$ = useRef$<HTMLDivElement>();
const { isActive$, pause, resume } = useIntersectionObserver( el$, (entries) => { entries.forEach((entry) => { console.log(entry.isIntersecting); }); }, { threshold: 0.5 } );
return <div ref={el$} />;}Threshold array
Section titled “Threshold array”Trigger the callback at multiple intersection ratios:
useIntersectionObserver(el$, callback, { threshold: [0, 0.25, 0.5, 0.75, 1],});Custom root and rootMargin
Section titled “Custom root and rootMargin”useIntersectionObserver(el$, callback, { root: scrollContainerEl, rootMargin: "0px 0px -100px 0px",});Reactive root / rootMargin
Section titled “Reactive root / rootMargin”Pass an Observable to reactively recreate the observer when the value changes:
const rootMargin$ = observable("0px");
useIntersectionObserver(el$, callback, { rootMargin: rootMargin$ });
// later — observer is automatically recreated with new marginrootMargin$.set("-50px 0px");Deferred start
Section titled “Deferred start”Set immediate: false to start observation manually:
const { resume } = useIntersectionObserver(el$, callback, { immediate: false });
resume(); // starts observingPause and resume
Section titled “Pause and resume”const { pause, resume } = useIntersectionObserver(el$, callback);
pause(); // disconnects the observer, isActive$ → falseresume(); // reconnects the observer, isActive$ → truePermanent stop
Section titled “Permanent stop”const { stop } = useIntersectionObserver(el$, callback);
stop(); // disconnects and prevents future resume()Checking browser support
Section titled “Checking browser support”const { isSupported$ } = useIntersectionObserver(el$, callback);
console.log(isSupported$.get()); // Observable<boolean>Type Declarations
Section titled “Type Declarations”export interface UseIntersectionObserverOptions { immediate?: boolean; root?: MaybeElement; rootMargin?: string; threshold?: number | number[];}export interface UseIntersectionObserverReturn { isSupported$: ReadonlyObservable<boolean>; isActive$: ReadonlyObservable<boolean>; stop: () => void; pause: () => void; resume: () => void;}export declare function useIntersectionObserver(target: MaybeElement | MaybeElement[], callback: IntersectionObserverCallback, options?: DeepMaybeObservable<UseIntersectionObserverOptions>): UseIntersectionObserverReturn;Source
Section titled “Source”Contributors
Section titled “Contributors”- tigerwest
Changelog
Section titled “Changelog”a7392ab2026-03-06 - feat(core,browser): add sync strategy hooks (tigerwest)