# useMediaQuery

> A React useMediaQuery hook that is SSR-safe, plus hooks for phone widths, touch screens and the current Tailwind breakpoint.

- Type: React hook (Hooks & Utilities)
- Access: Free (the source is open to everyone)
- Version: 1.0.0
- Install: `npx wingo-ui@latest add use-media-query`
- Docs: https://wingo-ui.com/components/use-media-query

## Interaction

Resize the window, switch to the phone frame or change your system settings: the readout follows along live. Type any media query into the playground to test it.

## Installation

```bash
npx wingo-ui@latest add use-media-query
```

The CLI adds the files, their dependencies and a version record for updates.

With shadcn: `npx shadcn@latest add https://wingo-ui.com/r/use-media-query.json`

Files:

- `hooks/use-media-query.ts`

## Usage

```tsx
import { useBreakpoint, useIsMobile, useIsTouch, useMediaQuery } from "@/hooks/use-media-query"

export function PhotoGrid({ photos }: { photos: string[] }) {
  const isMobile = useIsMobile()
  const isTouch = useIsTouch()
  const breakpoint = useBreakpoint()
  const landscape = useMediaQuery("(orientation: landscape)")
  const columns = isMobile ? (landscape ? 3 : 2) : breakpoint === "2xl" ? 5 : 4

  return (
    <ul className="grid gap-2" style={{ gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))` }}>
      {photos.map((src) => (
        // touch screens have no hover, so the caption is always visible there
        <li key={src} className="group relative">
          <img src={src} alt="" className="aspect-square w-full rounded-xl object-cover" />
          <span className={isTouch ? "absolute bottom-2 left-2" : "absolute bottom-2 left-2 opacity-0 group-hover:opacity-100"}>View</span>
        </li>
      ))}
    </ul>
  )
}
```

## API

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `query` | `string` | `"(min-width: 1024px)"` | useMediaQuery(query, serverFallback?): any CSS media query. Returns true while it matches and re-renders when that flips. |
| `serverFallback?` | `boolean` | `false` | What useMediaQuery returns on the server and during hydration, before the browser can answer. Pick the value your server layout assumes. |
| `returns?` | `boolean` |  | Whether the query matches right now; serverFallback until the component has hydrated. |

## Parts

### useIsMobile (hook)

True below 768px (Tailwind md). The switch point where popovers, selects and menus become bottom sheets. Signature: () => boolean.

### useIsTouch (hook)

True when the primary pointer is coarse (a finger). Use it for 44px targets and to skip hover-only affordances. Signature: () => boolean.

### useBreakpoint (hook)

The widest Tailwind breakpoint that matches, with one subscription for all of them. Signature: (serverFallback?: Breakpoint) => "base" | "sm" | "md" | "lg" | "xl" | "2xl".

### matchesMedia (function)

The same check outside render, for event handlers and effects. False on the server. Signature: (query: string) => boolean.

### useIsApple (hook)

Whether the device is a Mac, iPhone or iPad, for shortcut notation (⌘K vs Ctrl+K) and for binding mod to the meta key. The hook is false on the server and during hydration. Signature: () => boolean.

### isApple (function)

The same check as useIsApple outside render, for event handlers that bind mod to the meta key. False on the server. Signature: () => boolean.

### BREAKPOINTS (constant)

The Tailwind breakpoint widths in px: sm 640, md 768, lg 1024, xl 1280, 2xl 1536. useBreakpoint reads them.

### MOBILE_QUERY (constant)

"(max-width: 767.98px)", what useIsMobile watches: below Tailwind md, where overlays become bottom sheets.

### TOUCH_QUERY (constant)

"(pointer: coarse)", what useIsTouch watches: the primary pointer is a finger.

### HOVER_QUERY (constant)

"(hover: hover) and (pointer: fine)": a mouse or trackpad that can hover, for hover-only effects.

### REDUCED_MOTION_QUERY (constant)

"(prefers-reduced-motion: reduce)": the system asks for less motion.

### DARK_SCHEME_QUERY (constant)

"(prefers-color-scheme: dark)": the system theme is dark.

### Breakpoint (type)

What useBreakpoint returns: "base" | "sm" | "md" | "lg" | "xl" | "2xl".

## Examples

- **Responsive columns**: useBreakpoint picks how many listing cards fit per row.
- **Sheet or popover**: useIsMobile and useIsTouch decide how overlays and row actions behave.
- **Any media query**: useMediaQuery with a custom query and a server fallback.

## See also

- [Motion presets](https://wingo-ui.com/components/motion) ([Markdown](https://wingo-ui.com/components/motion.md))
- [useControllableState](https://wingo-ui.com/components/use-controllable-state) ([Markdown](https://wingo-ui.com/components/use-controllable-state.md))
- [Drawer](https://wingo-ui.com/components/drawer) ([Markdown](https://wingo-ui.com/components/drawer.md))
- [Button](https://wingo-ui.com/components/button) ([Markdown](https://wingo-ui.com/components/button.md))

---

Canonical: https://wingo-ui.com/components/use-media-query
More components: https://wingo-ui.com/components · Index for agents: https://wingo-ui.com/llms.txt
