Skip to content

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$} />;
}

Trigger the callback at multiple intersection ratios:

useIntersectionObserver(el$, callback, {
threshold: [0, 0.25, 0.5, 0.75, 1],
});
useIntersectionObserver(el$, callback, {
root: scrollContainerEl,
rootMargin: "0px 0px -100px 0px",
});

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 margin
rootMargin$.set("-50px 0px");

Set immediate: false to start observation manually:

const { resume } = useIntersectionObserver(el$, callback, { immediate: false });
resume(); // starts observing
const { pause, resume } = useIntersectionObserver(el$, callback);
pause(); // disconnects the observer, isActive$ → false
resume(); // reconnects the observer, isActive$ → true
const { stop } = useIntersectionObserver(el$, callback);
stop(); // disconnects and prevents future resume()
const { isSupported$ } = useIntersectionObserver(el$, callback);
console.log(isSupported$.get()); // Observable<boolean>
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;

View on GitHub

  • tigerwest
  • a7392ab 2026-03-06 - feat(core,browser): add sync strategy hooks (tigerwest)