useReducedMotion
Live prefers-reduced-motion match without an animation library. Renders false on the server, so hydration never mismatches, and updates when the setting changes.
Example
Installation
npx shadcn@latest add https://hirael.com/r/use-reduced-motion.jsonUsage
import { useReducedMotion } from "@/hooks/use-reduced-motion"Paths assume the default @/ alias from your components.json.
API
useReducedMotion()
Takes no arguments.
Returns
booleanSource
import * as React from 'react';
const REDUCED_MOTION = '(prefers-reduced-motion: reduce)';
const subscribe = (onStoreChange: () => void) => {
const query = window.matchMedia(REDUCED_MOTION);
query.addEventListener('change', onStoreChange);
return () => query.removeEventListener('change', onStoreChange);
};
/** Live `prefers-reduced-motion` match. The server and hydration render read `false`. */
export const useReducedMotion = () =>
React.useSyncExternalStore(
subscribe,
() => window.matchMedia(REDUCED_MOTION).matches,
() => false,
);
Shipped