useMediaQuery
React to breakpoints and prefers-color-scheme
From the Custom Hooks collection. Reads a media query via matchMedia and
re-renders when it changes — to decide layout in JS or react to the system theme.
import { useEffect, useState } from "react";
const useMediaQuery = (query: string): boolean => {
// Guard against SSR: window doesn't exist on the server.
const [matches, setMatches] = useState(
() => typeof window !== "undefined" && window.matchMedia(query).matches,
);
useEffect(() => {
const mql = window.matchMedia(query);
const onChange = () => setMatches(mql.matches);
onChange(); // sync on mount (the query may have changed).
mql.addEventListener("change", onChange);
return () => mql.removeEventListener("change", onChange);
}, [query]);
return matches;
};
export default useMediaQuery;
⚠️ Prefer CSS media queries for pure styling; use this hook when the decision changes the logic/JSX (rendering different components, for example).
Example — pairs with the dark/light theme from the HTML template:
const isDark = useMediaQuery("(prefers-color-scheme: dark)");
const isWide = useMediaQuery("(min-width: 768px)");
return isWide ? <Sidebar /> : <Drawer />;
Related: Custom Hooks · use-local-storage · HTML template.