useWindowScroll
Tracks the window scroll position, direction, arrived state, and scrolling status as reactive Observable values. A convenience wrapper around useScroll(window).
x: 0y: 0idle
topbottomleftright
Scroll the page to see the values update in real time.
import { import useWindowScroll
useWindowScroll } from "@usels/core";
function function Component(): React.JSX.Element
Component() { const { const x: any
x, const y: any
y, const arrivedState: any
arrivedState } = import useWindowScroll
useWindowScroll();
return ( <React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> scrollX: {const x: any
x.any
get()}, scrollY: {const y: any
y.any
get()} {const arrivedState: any
arrivedState.any
bottom.any
get() && " — reached bottom"} </React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> );}Back-to-top button
Section titled “Back-to-top button”import { import useWindowScroll
useWindowScroll } from "@usels/core";
function function BackToTop(): React.JSX.Element | null
BackToTop() { const { const arrivedState: any
arrivedState } = import useWindowScroll
useWindowScroll();
return !const arrivedState: any
arrivedState.any
top.any
get() ? ( <React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button React.DOMAttributes<HTMLButtonElement>.onClick?: React.MouseEventHandler<HTMLButtonElement> | undefined
onClick={() => any
window.any
scrollTo({ top: number
top: 0, behavior: string
behavior: "smooth" })}>↑ Back to top</React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button> ) : null;}Scroll direction indicator
Section titled “Scroll direction indicator”const { directions } = useWindowScroll();// directions.bottom.get() → true while scrolling down// directions.top.get() → true while scrolling upInfinite scroll trigger
Section titled “Infinite scroll trigger”import { useObserveEffect } from "@legendapp/state/react";
const { arrivedState } = useWindowScroll({ offset: { bottom: 200 } });
useObserveEffect(arrivedState.bottom, (e) => { if (e.value) fetchNextPage();});isScrolling + onStop
Section titled “isScrolling + onStop”const { isScrolling } = useWindowScroll({ idle: 300, onStop: () => saveScrollPosition(),});Throttled updates
Section titled “Throttled updates”const { y } = useWindowScroll({ throttle: 100 });SSR-safe. When window is not available (SSR), useWindowScroll passes null to useScroll, so all observables hold initial values (x: 0, y: 0, isScrolling: false) and no event listener is registered.
See useScroll for the full API reference including all options.
Type Declarations
Section titled “Type Declarations”export type { UseScrollOptions, UseScrollReturn };export declare function useWindowScroll(options?: UseScrollOptions): UseScrollReturn;Source
Section titled “Source”Contributors
Section titled “Contributors”- tigerwest
Changelog
Section titled “Changelog”a7392ab2026-03-06 - feat(core,browser): add sync strategy hooks (tigerwest)