useMediaQuery

A React hook for efficiently handling responsive design with media queries. Provides real-time viewport updates, supports complex media queries, and handles SSR gracefully. Perfect for building responsive layouts and implementing device-specific features.

Live Demo

Current Breakpoint:

📱 Mobile: No

📟 Tablet: No

🖥️ Desktop: No

Implementation

export function useMediaQuery(query: string) {
  // Initialize with null during SSR
  const [matches, setMatches] = useState<boolean>(() => {
    // Check if window is available (client-side)
    if (typeof window !== "undefined") {
      return window.matchMedia(query).matches;
    }
    return false;
  });

  useEffect(() => {
    // Return early if no window object
    if (typeof window === "undefined") return;

    const mediaQuery = window.matchMedia(query);

    // Set initial value
    setMatches(mediaQuery.matches);

    // Create event listener function
    const handleChange = (event: MediaQueryListEvent) => {
      setMatches(event.matches);
    };

    // Add event listener
    mediaQuery.addEventListener("change", handleChange);

    // Cleanup
    return () => {
      mediaQuery.removeEventListener("change", handleChange);
    };
  }, [query]); // Re-run effect if query changes

  return matches;
}

Usage

// Basic usage
const isMobile = useMediaQuery('(max-width: 768px)');

// Multiple queries
const isTablet = useMediaQuery('(min-width: 769px) and (max-width: 1024px)');
const isDarkMode = useMediaQuery('(prefers-color-scheme: dark)');

// Use in conditional rendering
{isMobile ? <MobileNav /> : <DesktopNav />}

Important Notes

Server-Side Rendering (SSR) Considerations

This hook is designed to work safely in SSR environments:

  • During SSR, the hook will return false as default
  • Media query matching is only performed on the client-side
  • The hook includes checks for window object availability
  • Event listeners are properly cleaned up to prevent memory leaks