Overview
TheuseIntersectionObserver hook provides a simple interface to detect when an element becomes visible in the viewport. It’s perfect for implementing scroll-based animations, lazy loading, and performance optimizations.
This hook automatically handles browser compatibility by checking for Intersection Observer API support. Components will gracefully degrade in unsupported browsers.
Import
Usage
Basic Visibility Detection
Scroll-Triggered Animation
Lazy Loading Images
Tracking Multiple Elements
Parameters
The hook accepts an optional options object:A number between 0 and 1 indicating what percentage of the element must be visible to trigger the observer.
0: Triggers as soon as any part enters viewport0.5: Triggers when 50% is visible1: Triggers only when fully visible
Margin around the viewport for triggering the observer early or late. Uses CSS margin syntax.Examples:
'0px': Trigger at viewport edge'100px': Trigger 100px before entering viewport'-50px': Trigger 50px after entering viewport'100px 0px': 100px top/bottom, 0px left/right
If
true, stops observing after the element becomes visible once. Useful for one-time animations.This prevents the element from toggling visibility when scrolling back up.Return Value
The hook returns an object with the following properties:A React ref to attach to the element you want to observe. Must be assigned to the element’s
ref prop.Boolean indicating whether the element is currently visible in the viewport based on the configured options.Updates whenever the element enters or exits the viewport (unless
freezeOnceVisible is true).The raw Intersection Observer entry object containing detailed information about the intersection.Useful properties:
entry.isIntersecting: Same asisVisibleentry.intersectionRatio: How much of the element is visible (0-1)entry.boundingClientRect: Element’s position and sizeentry.intersectionRect: The visible portion of the element
Type Definitions
Implementation Details
Browser Support Check
The hook checks for Intersection Observer support:Freeze Mechanism
WhenfreezeOnceVisible is true, observation stops after first intersection:
Cleanup
The hook automatically disconnects the observer when the component unmounts:Use Cases
- Scroll animations: Trigger animations when elements enter viewport
- Lazy loading: Load images, videos, or components only when needed
- Analytics: Track when users view specific content
- Infinite scroll: Load more content when reaching bottom
- Performance: Defer expensive renders until elements are visible
- Reveal effects: Progressive disclosure of content as user scrolls
Performance Considerations
Advantages Over Scroll Listeners
Intersection Observer is more performant than scroll event listeners because:
- Runs asynchronously without blocking main thread
- Browser-optimized for intersection calculations
- No need for manual throttling or debouncing
- Automatically handles reflows and resizes
Best Practices
- Use
freezeOnceVisiblefor one-time animations to stop observing after trigger - Adjust
thresholdbased on element size (smaller elements need lower thresholds) - Use
rootMarginto preload content before it becomes visible - Batch animations by observing multiple elements with the same options
Common Patterns
One-Time Reveal Animation
Early Loading Trigger
Precise Visibility Requirement
Browser Compatibility
Intersection Observer is supported in all modern browsers:- Chrome 51+
- Firefox 55+
- Safari 12.1+
- Edge 15+
Troubleshooting
Element Not Detected
Ensure the ref is attached correctly:Animation Triggers Too Early
Increase threshold or use negative rootMargin:Content Loads Too Late
Use positive rootMargin to trigger earlier:Related
- useDeviceType - Device detection for responsive behavior
- Framer Motion - Animation library that pairs well with this hook
- Intersection Observer API - MDN documentation
