Skip to main content

useOnScreen

useOnScreen is a custom React hook that reports whether an element is visible within the viewport using IntersectionObserver.

Usage

import { useOnScreen } from "hookify-react";

export default function UseOnScreenExample() {
const { ref, isVisible } = useOnScreen<HTMLDivElement>({
rootMargin: "-100px",
once: true,
});

return (
<div>
<div style={{ height: "100svh" }}>Scroll down to see the box</div>
<div
ref={ref}
style={{
height: "400px",
backgroundColor: isVisible ? "lightgreen" : "lightcoral",
display: "flex",
alignItems: "center",
justifyContent: "center",
fontSize: "20px",
}}
>
{isVisible ? "I'm visible! 🎉" : "Not in view 👀"}
</div>
</div>
);
}

API Reference

Parameters

useOnScreen accepts a single optional options argument that is either a rootMargin string (for backwards compatibility) or an options object.

ParameterTypeDefaultDescription
optionsstring | OnScreenOptions"0px"A rootMargin string, or an options object (see below).

When options is an object (OnScreenOptions):

FieldTypeDefaultDescription
rootMarginstring"0px"Margin around the root, like CSS margin (e.g. "-100px").
thresholdnumber | number[]0Intersection ratio(s) at which the visibility state updates.
oncebooleanfalseWhen true, stops observing once the element becomes visible.

Return Value

useOnScreen returns an object with the following properties:

PropertyTypeDescription
refReact.MutableRefObject<T | null>A ref to attach to the target element.
isVisiblebooleantrue while the element intersects the viewport, otherwise false.

Behavior

  • Uses IntersectionObserver to track whether the element intersects the viewport.
  • Updates isVisible as the element enters and exits the viewport.
  • With once: true, disconnects the observer after the element first becomes visible.
  • Ideal for lazy loading, scroll-triggered animations, or firing events when an element comes into view.

SSR Safety

useOnScreen is safe during server-side rendering and in browsers without IntersectionObserver. It guards against a missing observer and simply reports false instead of throwing.