Documentation

Hooks

useIntersectionObserver

Find out when an element scrolls into view. Use it for lazy loading, infinite feeds and "seen" tracking.

Preview

Latest threadsScroll down
Welcome to the community!
How do I reset my password?
Dark mode looks great
Plugin ideas for 2026
Weekly showcase thread
Server moved to a new host
You have read everything. Go touch some grass.

Usage

import { useIntersectionObserver } from '@vitnode/core/hooks/use-intersection-observer'
const [element, setElement] = React.useState<HTMLDivElement | null>(null)
const entry = useIntersectionObserver(element, { threshold: 0.5 })

return (
  <div ref={setElement}>
    {entry?.isIntersecting ? 'I can see you!' : 'Nobody is looking...'}
  </div>
)

It returns the latest IntersectionObserverEntry, or undefined until the first report. On the server, and in browsers without IntersectionObserver, it stays undefined.

Keep the element in state through a callback ref, not useRef. Then the hook notices when the node mounts late or gets swapped.

Load once, then stop

freezeOnceVisible stops observing the first time the element shows up. A positive rootMargin starts loading just before it reaches the screen.

const entry = useIntersectionObserver(element, {
  freezeOnceVisible: true,
  rootMargin: '200px',
})

return (
  <div ref={setElement}>{entry?.isIntersecting ? <HeavyChart /> : null}</div>
)

Inside a scroll container

The preview above watches its own scroll box, not the viewport. Pass that box as root, stored in state the same way:

const [root, setRoot] = React.useState<HTMLDivElement | null>(null)
const entry = useIntersectionObserver(element, { root })

Options

Prop

Type