shadcn.io is an independent project built on shadcn/ui
useMousePosition returns the pointer position on the page. Put the ref on an element and the same tuple also carries coordinates inside that element.
Page coordinates include scroll. To measure the element box instead of the pointer, use useResizeObserver. In React the numbers start at zero, and the listener attaches after the first paint.
Installation
Anatomy

Usage
import { useMousePosition } from "@/hooks/use-mouse-position";const [position, ref] = useMousePosition<HTMLDivElement>();Read x and y for the page. Attach the ref to also receive elementX and elementY, measured from the element's top-left.
FAQ
How do I get coordinates inside an element?
Put the ref from the tuple on the element. On each move the hook reads that element's rectangle, adds the page scroll, and subtracts the result from the page coordinates. elementX and elementY are those differences. elementPositionX and elementPositionY are the element's top-left on the page. Until the ref points at an element, only x and y are set.
Do the coordinates include scroll?
Yes. x and y come from pageX and pageY, which measure from the document rather than the current viewport. Element coordinates start from getBoundingClientRect, then add scrollX and scrollY, so scrolling the page does not move the origin. The hook does not listen to scroll by itself. The numbers refresh on the next mousemove.
Does this track touch?
No. The only listener is mousemove on the document. A finger does not fire that event, so the stored position stays where it was. There is no pointermove or touchmove subscription. If you need mouse and touch together, use a different listener. The coordinates start at zero and stay there until a mouse actually moves.
What does the server return?
x and y are zero, and the element fields are absent, because the listener is added in an effect. Render does not read window, so the server HTML matches the client's first paint. After mount, one document listener is attached. Each move replaces the whole position object. Unmounting removes the listener.
Which element type does the ref expect?
The generic is the element you will attach, and it has to extend HTMLElement. A call for a div gives you a ref whose current value starts as null and later holds that div. The hook checks that the node is an element before it reads a rectangle. Leave the ref unset and you still get page coordinates.
How often does it re-render?
Once per mousemove for as long as the component is mounted. Every event stores a new position object, even when the numbers barely change. That suits a badge or a small preview. A heavy render should not subscribe here, because the hook does not throttle and it does not pause when the pointer leaves the element.
API Reference
Returns
[0] positionPosition
Where the pointer is.
position.elementPositionX?number
The element's left edge, from the page's left. With the ref attached.
position.elementPositionY?number
The element's top edge, from the page's top. With the ref attached.
position.elementX?number
The pointer's distance from the element's left edge. With the ref attached.
position.elementY?number
The pointer's distance from the element's top edge. With the ref attached.
position.xnumber
The pointer's distance from the page's left (pageX).
position.ynumber
The pointer's distance from the page's top (pageY).
[1] refReact.RefObject<T | null>
Attach to an element to get positions relative to it too.
- Type
React.RefObject<T | null>













