Octocat

usePrefersReducedMotion

A hook for checking user preference for reduce motion

Source Code

'use client';

import { useEffect, useState } from 'react';

const QUERY = '(prefers-reduced-motion: no-preference)';

const usePrefersReducedMotion = (): boolean => {
  const [prefersReducedMotion, setPrefersReducedMotion] =
    useState<boolean>(false);

  useEffect(() => {
    const mediaQueryList = window.matchMedia(QUERY);

    const listener = (event: MediaQueryListEvent) => {
      setPrefersReducedMotion(!event.matches);
    };

    mediaQueryList.addEventListener('change', listener);

    return () => {
      mediaQueryList.removeEventListener('change', listener);
    };
  }, []);

  return prefersReducedMotion;
};

export default usePrefersReducedMotion;

API Reference

This hook returns a boolean indicating whether the user has enabled reduced motion preferences in their system settings. When true, it suggests the user prefers minimal or no animation effects.

Examples

Basic

'use client';

import usePrefersReducedMotion from '../use-prefers-reduced-motion';

const UserPrefersReducedMotionPreview = () => {
  const prefersReducedMotion = usePrefersReducedMotion();

  return (
    <video autoPlay={!prefersReducedMotion} controls className="h-full w-full">
      <source
        src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
        type="video/mp4"
      />
      Your browser does not support the video tag.
    </video>
  );
};

export default UserPrefersReducedMotionPreview;

Best Practices

This setting should be checked before implementing animations to ensure compliance with WCAG accessibility guidelines. When true, animations should be disabled or simplified to accommodate users who have enabled reduced motion preferences in their system settings.

Note

For projects that already has motion installed, this hook already exists here. Also to note tailwindcss has motion-reduce

Previous

useMousePan

Next

useScrollLock