mwui
GitHub

useMediaQuery

A hook that tracks a CSS media query without tearing during hydration.

smno match
mdno match
lgno match
Darkno match
Reduced motionno match

Resize the window to see these change.

Installation

Usage

Subscribes to a CSS media query and re-renders when it starts or stops matching.

import { useMediaQuery } from "@/hooks/use-media-query";

function Navigation() {
  const isDesktop = useMediaQuery("(min-width: 768px)");

  return isDesktop ? <Sidebar /> : <MobileDrawer />;
}

Server rendering

The hook is built on useSyncExternalStore, which takes a separate server snapshot. On the server and during the first client render it returns defaultValue, then switches to the real result — so React never has to reconcile two different trees for the same commit.

const prefersReducedMotion = useMediaQuery("(prefers-reduced-motion: reduce)", {
  defaultValue: true,
});

Pick the defaultValue that matches the markup you render on the server. For layout queries that usually means the mobile branch; for prefers-reduced-motion it usually means the safe one.

Prefer CSS where you can. A media query in CSS costs nothing and never mismatches. Reach for this hook when the breakpoint has to change what renders — a different component, a different DOM structure — not just how it looks.

Notes

  • The query string is passed straight to window.matchMedia, so any valid media query works.
  • Changing query resubscribes automatically.
  • Listeners are registered with addEventListener, and are cleaned up on unmount.