All hooks / Viewport and media

useMediaQuery

126 B minified and brotliedSourceMarkdown✓ Works in all modern browsers

Tracks whether a CSS media query matches, and re-renders when it changes.

Renders serverValue on the server and during hydration, then switches to the real value with no hydration mismatch. Concurrent-safe: every component reads the same value in one render.

Import

import { useMediaQuery } from '@vincent.ri/react-tils'
// or only this hook
import { useMediaQuery } from '@vincent.ri/react-tils/useMediaQuery'

Usage

const isWide = useMediaQuery('(min-width: 768px)')
const prefersDark = useMediaQuery('(prefers-color-scheme: dark)')
// Mobile-first site: assume narrow on the server.
const isDesktop = useMediaQuery('(min-width: 1024px)', false)

Live demo

Resize the window, or switch your OS theme.

narrowlight

When to use it

JS logic depends on viewport size, prefers-color-scheme, prefers-reduced-motion, pointer type, or orientation.

When not to

Only styling changes. Use a CSS @media rule instead, which needs no JS and never flashes.

API

function useMediaQuery(query: string, serverValue?: boolean): boolean
ParameterDescription
queryAny CSS media query, e.g. '(min-width: 768px)'.
serverValueValue on the server and during hydration. Pick the value most visitors will have, to minimize the switch after hydration. Default false.

Browser support

UsesChromeEdgeFirefoxSafariChrome AndroidSafari iOS
matchMediaWidely available9+12+6+5.1+18+5+

First version with support, from MDN's compatibility data (web-features 3.42.0, @mdn/browser-compat-data 8.1.5).

Coming from another library?

Other libraries call this useMedia, useBreakpoint, useResponsive.