# React Intersection Observer > React hooks and components for the Intersection Observer API. Scroll animations, lazy loading, impressions, and infinite scroll. ## Docs - [Overview](/overview): React hooks and components that tell you when an element enters or leaves the viewport or a scroll container. ## API - [Core APIs](/api/core-apis): Choose and use the three React APIs for observing elements. - [Observer options](/api/configuration): Decide when observation should trigger, where it should happen, and how long it should run. ## Guides - [Recipes](/guides/recipes): Complete visibility-aware React patterns built with react-intersection-observer. - [SSR and fallbacks](/guides/ssr): Separate server-rendered state, unsupported browsers, hydration, and application fallback policy. - [Observer v2](/guides/intersection-observer-v2): Use trackVisibility only when intersection alone is not enough and you accept narrower browser support. ## Testing - [Testing](/testing): Choose the test layer that matches the behavior you need to prove. - [Browser Mode](/testing/browser-mode): Use Vitest Browser Mode to test real scrolling, layout, focus, and native Intersection Observer behavior. - [Mock intersections](/testing/mocking-intersections): Drive deterministic observer callbacks and thresholds in Vitest, Jest, or another DOM-capable test runner. ## Changelog - [v11.0.1](/changelog/v11-0-1): Fix docs callouts and logo theming by @thebuilder in https://github.com/thebuilder/react-intersection-observer/pull/776Agent/docs callouts and logo theme by… - [v11.0.0](/changelog/v11-0-0): v11 delivers a ground-up observer lifecycle rewrite, making observation and cleanup more resilient across React 17, 18, and 19. Shared callback-ref handling… - [v10.1.0](/changelog/v10-1-0): chore: update github actions by @thebuilder in https://github.com/thebuilder/react-intersection-observer/pull/754Add support for scrollMargin option for… - [v10.0.3](/changelog/v10-0-3): prevent callback skipping with triggerOnce and merged refs by @djk01281 in https://github.com/thebuilder/react-intersection-observer/pull/747 @djk01281 made… - [v10.0.2](/changelog/v10-0-2): Add npm package size badge to README by @jantimon in https://github.com/thebuilder/react-intersection-observer/pull/740feat: bump dependencies by @thebuilder… - [v10.0.0](/changelog/v10-0-0): Based on the great work in #718 by @jantimon - This release adds the new useOnInView hook. useOnInView hook — a no-re-render alternative to useInView that… - [v9.16.0](/changelog/v9-16-0): ci: drop semantic release flow by @thebuilder in https://github.com/thebuilder/react-intersection-observer/pull/719Correctly detect global testing framework… - [v9.15.1](/changelog/v9-15-1): Fixes and improvements to react-intersection-observer/test-utils always recreate the IntersectionObserver mock (c720914)improve test lib detection… - [v9.15.0](/changelog/v9-15-0): restore beforeEach in test utils (788dd47) - [v9.14.1](/changelog/v9-14-1): ensure browser environment in test-utils (6e459f2) - [v9.14.0](/changelog/v9-14-0): support React 19 (8bafe25)Drop support for React 15/16. The types are no longer compatible with later version of React, since they have dropped the deprecated… - [v9.13.1](/changelog/v9-13-1): align IntersectionObserver options with DOM API (abb4ee8) - [v9.13.0](/changelog/v9-13-0): fix package exports and simplify build (#695) (c9cef8f) - All thanks go to @RobinTail - [v9.12.0](/changelog/v9-12-0): upgrade to Vitest 2 (#690) (054adf4)Upgrade to Vitest 2Add basic browser mode test, that runs with an unmocked IntersectionObserverTypes cleanup in… - [v9.11.0](/changelog/v9-11-0): remove script to publish dist dir (0980efa) - [v9.10.3](/changelog/v9-10-3): test-utils - execute mockClear method only when it exists (712ae37) - [v9.10.2](/changelog/v9-10-2): support old act from react-dom (0e95b5d) - [v9.10.1](/changelog/v9-10-1): use act from react instead of deprecated one (87258aa) - [v9.10.0](/changelog/v9-10-0): replace codesandbox with stackblitz (b0205ee) - [v9.9.0](/changelog/v9-9-0): replace codesandbox with stackblitz (efac8ee) - [v9.8.2](/changelog/v9-8-2): test utils, only use act when in an act environment (3c515e7) - [v9.8.1](/changelog/v9-8-1): include "type": "commonjs" in package.json (684affe) - [v9.8.0](/changelog/v9-8-0): export .mts for test-utils (05236e7) - [v9.7.0](/changelog/v9-7-0): This release switches from ESLint and Prettier to Biome.js, as a way of cutting down on dev dependencies and configuration. migrate to Biome.js formatting… - [v9.6.0](/changelog/v9-6-0): mark react-dom as optional (00a9139) add react-dom as a peer dependency (8f67987) - [v9.5.4](/changelog/v9-5-4): export .d.mts file for types (7e2c575) - [v9.5.3](/changelog/v9-5-3): add componentDidMount to InView (5da81d2), closes #649 - [v9.5.2](/changelog/v9-5-2): target es2018 (4c110ac) - [v9.5.1](/changelog/v9-5-1): improve bundle output (b24d9b2)output legacy esm (00faf77) - [v9.5.0](/changelog/v9-5-0): This release switches the build tool to tsup, in order for the package to support the use client directive. Hopefully it shouldn't have an impact on usage… - [v9.4.4](/changelog/v9-4-4): correct the error message that happens if IntersectionObserver is not mocked (f7da436) - [v9.4.3](/changelog/v9-4-3): restrict type on the "as" prop (048bcb0) - [v9.4.2](/changelog/v9-4-2): remove extra useEffect used for resetting initial state (#607) publish main with semantic releases (6711bc1)rename master to main (11d5bd1) - [v9.4.1](/changelog/v9-4-1): add spacing to peer deps (1187726)cannot access 'unobserve' before initialization #587 (3c2f4a1) - [v9.4.0](/changelog/v9-4-0): This release fixes https://github.com/thebuilder/react-intersection-observer/issues/572 It's now possible (not recommended) to use inline functions for ref… - [v9.3.5](/changelog/v9-3-5): Add support for TS 4.7+ node16/next module (a0c099b) - [v9.3.4](/changelog/v9-3-4): export module as esm.js (fa6f3db) - [v9.3.3](/changelog/v9-3-3): use the default field (24be995) - [v9.3.2](/changelog/v9-3-2): correct the build copy (88058e1)export paths with dot path (5d36ed6) - [v9.3.1](/changelog/v9-3-1): export the test utils (cbbdfa3) - [v9.3.0](/changelog/v9-3-0): refactor to use modern exports (bc0daf6) - [v9.2.2](/changelog/v9-2-2): correct broken module exports (12bad4a)correct name in size limit (3d4534e)revert the bundle changes (e7ac6d2) - [v9.2.1](/changelog/v9-2-1): correct microbundle output paths (0f55aa2) - [v9.2.0](/changelog/v9-2-0): Switch to vitest and storybook vite (#549) (af0440f)Support both Jest and Vitest in test-utilsImprove readme section on testing - [v9.1.0](/changelog/v9-1-0): support onChange on useInView (ba8d059) - [v9.0.0](/changelog/v9-0-0): This release is mainly to fix an issue with the exports not being properly tree-shaken. Fix tree shaking (#545) (f0571d8), closes #544 After tree shaking… - [v8.34.0](/changelog/v8-34-0): upgrade to React 18 (#538) (98bb83f)Upgrade Storybook and other dev dependencies. This removes the old tag prop from , that was deprecated by as some… - [v8.33.1](/changelog/v8-33-1): Update test-utils.ts (#525) (e217965) - [v8.33.0](/changelog/v8-33-0): add support for fallbackInView (#521) (aa50422) - Closes #495 This is solution for #495 that adds support for a fallbackInView value. You can set the fallback… - [v8.32.5](/changelog/v8-32-5): undo the clear observers (#523) (249de1a) - [v8.32.4](/changelog/v8-32-4): correct import path for observermap (#522) (d4ecf3a) - [v8.32.3](/changelog/v8-32-3): clear observers after each test run (#519) (bc55d20) - [v8.32.2](/changelog/v8-32-2): make ratio return largest threshold smaller than trigger (#510) (f76fa78) - [v8.32.1](/changelog/v8-32-1): make children optional (#505) (d758a3e) - [v8.32.0](/changelog/v8-32-0): export the observe method (#473) (650e513), closes #402 - [v8.31.1](/changelog/v8-31-1): use WeakMap to avoid memory leak (#463) (47bad43), closes #462 - [v8.31.0](/changelog/v8-31-0): add support for testing threshold values (#417) (721cd61) - [v8.30.3](/changelog/v8-30-3): ensure threshold fallbacks to options value if undefined (#416) (88780d1) - [v8.30.2](/changelog/v8-30-2): ensure thresholds is defined (#415) (76405d7), closes #414 - [v8.30.1](/changelog/v8-30-1): ensure undefined values are filtered from id (9312d1d) - [v8.30.0](/changelog/v8-30-0): use beforeEach instead of beforeAll (#407) (c89385d) - [v8.29.1](/changelog/v8-29-1): stringify array thresholds (#404) (e903b1d) - [v8.29.0](/changelog/v8-29-0): support initialInView (#394) (2ce78b6) - [v8.28.6](/changelog/v8-28-6): optimize InView (#392) (b3e2959) - [v8.28.5](/changelog/v8-28-5): Detect inView if threshold is 1, closes #387 - [v8.28.4](/changelog/v8-28-4): optimize observers code (#385) (53024af) - [v8.28.3](/changelog/v8-28-3): check intersectionRatio in addition to isIntersecting (#384) (0252048) - [v8.28.2](/changelog/v8-28-2): add back default export for InView (#382) (9de54b7) - [v8.28.1](/changelog/v8-28-1): There was an issue with the CJS and UMD files generated by microbundle, not matching filename in package.json - [v8.28.0](/changelog/v8-28-0): modern rewrite (#370) (1537592) This is a rewrite of the internal handling of IntersectionObservers, alongside general refactoring and alignment of the code… - [v8.27.1](/changelog/v8-27-1): shouldn't trigger onchange when skipping (#365) (7aa5d74) - [v8.27.0](/changelog/v8-27-0): support skip option (#363) (6b4bd6d) - [v8.26.2](/changelog/v8-26-2): don't clear the inView state if we get a node (#337) (d1e1495), closes #308 - [v8.26.1](/changelog/v8-26-1): fix: the inView state could be reset with triggerOnce #311 (#312) a18d398 https://github.com/thebuilder/react-intersection-observer/compare/v8.26.0...v8.26.1 - [v8.26.0](/changelog/v8-26-0): Fix inView not reset when ref removed #303 (#306) 0c450ceFix Lazy Load Image example (#304) 211228a https://github.com/thebuilder/react-intersection-observer/c… - [v8.25.3](/changelog/v8-25-3): chore: upgrade dependencies 14afafbUpdate test-utils.ts (#302) e31086cchore(package): update @testing-library/jest-dom to version 5.0.0 (#292) 5ed2118Update… - [v8.25.2](/changelog/v8-25-2): chore: upgrade dependencies 23b1d51fix: Mock additional intersection properties (#286) aeae955chore: upgrade dependencies and readme 9348aabdocs: add Edit on… - [v8.25.1](/changelog/v8-25-1): fix: move tiny-invariant to dependencies a6c965e https://github.com/thebuilder/react-intersection-observer/compare/v8.25.0...v8.25.1 - [Build optimizations](/changelog/v8-25-0): build: optimize the rollup build 3cadc06 https://github.com/thebuilder/react-intersection-observer/compare/v8.24.2...v8.25.0 - [v8.24.2](/changelog/v8-24-2): fix: don't add onChange prop to the plain children container (#272) 4d88ea2Fix recipe for triggering animations (#271) 31a890bchore(package): update… - [v8.24.1](/changelog/v8-24-1): chore: upgrade dependencies 4734187refactor: switch to useCallback for setting node ref b31487bbuild(deps): bump lodash-es from 4.17.11 to 4.17.14 (#253)… - [Restructure package contents](/changelog/v8-23-0): This release restructures how the project is published to npm. Instead of publishing the entire project, it just publishes the content of the dist directory… - [TypeScript Tweaks](/changelog/v8-22-5): This release tweaks the Typescript typings for the PlainChildren version, so it should be more generic. - [v8.22.3](/changelog/v8-22-3): refactor: change the Map loop to forEach (#200) 831ca3a https://github.com/thebuilder/react-intersection-observer/compare/v8.22.2...v8.22.3 - [v8.22.2](/changelog/v8-22-2): Hooks were broken in last release - they would never trigger when they left the viewport. 😳 https://github.com/thebuilder/react-intersection-observer/compare/… - [Output test-utils.js to CommonJS](/changelog/v8-22-1): This fixes #197 and allows you to actually import the file into Jest. - [Rework some internals](/changelog/v8-22-0): Previously, the initial callback would trigger a state update, even if the element was still outside the viewport. This update changes the behavior, so it… - [Testing utils](/changelog/v8-20-0): This releases is focused on helping you when writing tests. In order to write meaningful tests, the IntersectionObserver needs to be mocked. If you are… - [Rewritten Hooks and tests](/changelog/v8-0-0): So now that Hooks have been out in the wild for a week, a few issues are starting to pop up. Especially relating to how refs are handled (#162). To fix this… - [TypeScript edition! 🎉](/changelog/v7-0-0): I decided to switch the project from Flow to TypeScript. This should ensure the TypeScript definitions match the actual implementation, without the need to… - [Intersection Ratio](/changelog/v6-4-0): This release exposes the intersectionRatio, giving you a bit more insight into what triggered an update. See #123 - [Hooks!](/changelog/v6-3-0): This release enables support for the useInView(ref, options) hook. The library will work fine with older versions of React, as long as you don't use the… - [Throw error if trying to observe element twice](/changelog/v6-2-3): This is a fix for #119 - [Babel 7](/changelog/v6-2-0): This release updates Babel and Rollup, and publishes the new output files. - [Keep plain children](/changelog/v6-1-0): Due to popular demand (#91), I'll keep support for rendering plain children inside the . This release just removes the deprecation flag. You don't… - [Simpler times](/changelog/v6-0-0): Looking at how i'm currently using react-intersection-observer, and how render props have been adapted by React, this release moves all rendering to to the… - [Keep on rolling](/changelog/v5-0-0): Switch the build system to Rollup, so the package now contains an umd, CommonJS and ES optimized build. 🎉 This shouldn't change anything if you are already… - [Render Props with refs](/changelog/v4-0-1): No more wrapping div element! render now gives complete control over the rendering, making it easier to use while keeping HTML semantic Removed… - [v3.0.1](/changelog/v3-0-1): This fixes #53 - [Render Prop Pattern](/changelog/v3-0-0): The render prop pattern recently became a popular replacement for the child as function pattern. Previously the render prop on react-intersection-observer… ## Agent resources - [llms-full.txt](/llms-full.txt): The full Markdown of every page in one file. - [Page Markdown](/index.md): Append `.md` to any page URL to fetch that page as raw Markdown. - [JSON API](/api/docs/pages.json): Page index of the JSON docs API; each entry links the page's JSON and Markdown forms. Described by the OpenAPI document at /openapi.json. - [API catalog](/.well-known/api-catalog): RFC 9727 linkset of the APIs documented here. - [agent-readability.json](/agent-readability.json): Manifest of every agent-facing artifact on this site.