useMediaQuery

Reactively tracks the state of a CSS media query.

Code

1import { useState, useEffect } from "react"
2
3export function useMediaQuery(query: string): boolean {
4  const [matches, setMatches] = useState(false)
5
6  useEffect(() => {
7    if (typeof window === "undefined") {
8      return
9    }
10
11    const mediaQueryList = window.matchMedia(query)
12    const listener = (event: MediaQueryListEvent) => setMatches(event.matches)
13
14    setMatches(mediaQueryList.matches)
15    mediaQueryList.addEventListener("change", listener)
16
17    return () => {
18      mediaQueryList.removeEventListener("change", listener)
19    }
20  }, [query])
21
22  return matches
23}

Usage Example

import { useMediaQuery } from "@/hooks/use-media-query" import { Card, CardContent } from "@/components/ui/card" export function MediaQueryExample() { const isDesktop = useMediaQuery("(min-width: 768px)") return ( <Card className="p-4"> <CardContent className="p-0"> <p className="text-lg"> {isDesktop ? "You are on a desktop screen." : "You are on a mobile screen."} </p> <p className="text-sm text-npui-muted-foreground mt-2"> (Resize your browser window to see the change) </p> </CardContent> </Card> ) }