Skip to content

useMediaQuery

What this solves

Responsive UI often requires JavaScript to know about viewport or media state:

  • Conditionally rendering components based on screen size
  • Adjusting behavior for mobile vs desktop
  • Responding to user preferences (reduced motion, color scheme)

useMediaQuery provides a reactive boolean that updates when a CSS media query matches or unmatches.


When to use it

Use this hook when you need to:

  • Conditionally render different components based on viewport
  • Adjust component behavior based on screen size
  • Respond to system preferences (prefers-reduced-motion, prefers-color-scheme)

When NOT to use it

  • For purely visual responsive changes — use CSS media queries directly
  • When Tailwind responsive classes are sufficient

Basic usage

tsx
import { useMediaQuery } from '@/shared/hooks'

export function ResponsiveNav() {
  const isMobile = useMediaQuery('(max-width: 768px)')

  if (isMobile) {
    return <MobileNav />
  }

  return <DesktopNav />
}

Common patterns

Pattern 1 — Breakpoint detection

tsx
import { useMediaQuery } from '@/shared/hooks'

export function Dashboard() {
  const isDesktop = useMediaQuery('(min-width: 1024px)')
  const isTablet = useMediaQuery('(min-width: 768px) and (max-width: 1023px)')
  const isMobile = useMediaQuery('(max-width: 767px)')

  return (
    <div>
      {isDesktop && <Sidebar />}
      <main>
        {isMobile ? <MobileCards /> : <DataTable />}
      </main>
    </div>
  )
}

Pattern 2 — System preferences

tsx
import { useMediaQuery } from '@/shared/hooks'

export function AnimatedComponent() {
  const prefersReducedMotion = useMediaQuery('(prefers-reduced-motion: reduce)')

  return (
    <div className={prefersReducedMotion ? '' : 'animate-fade-in'}>
      Content
    </div>
  )
}

API reference (concise)

ts
function useMediaQuery(query: string): boolean
ParameterTypeDescription
querystringA valid CSS media query string

Returns: booleantrue if the media query matches, false otherwise.


Notes

  • The hook handles SSR gracefully by returning false when window is undefined
  • Uses matchMedia API with proper event listener cleanup
  • Updates synchronously when the media query state changes