# useIsMobile

Detects whether the viewport matches a mobile max-width media query.

## Installation

```bash
npx shadcn@latest add https://reactdocs.canceydejean.dev/r/use-mobile.json
```

[Registry JSON](https://reactdocs.canceydejean.dev/r/use-mobile.json)

## Preview

```tsx
import { useIsMobile } from "@/hooks/use-mobile";

export function Preview() {
  const isMobile = useIsMobile();

  return (
    <div className="flex flex-col items-center gap-2 text-center">
      <p className="text-sm font-medium">{isMobile ? "Mobile viewport" : "Desktop viewport"}</p>
      <p className="text-sm text-muted-foreground">
        Resize below ~1024px (63.999rem) to see the value flip.
      </p>
    </div>
  );
}
```


## Source

### hooks/use-mobile.ts

```ts
import * as React from "react";

const MOBILE_BREAKPOINT_QUERY = "(max-width: 63.999rem)";

export function useIsMobile() {
  const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined);

  React.useEffect(() => {
    const mql = window.matchMedia(MOBILE_BREAKPOINT_QUERY);
    const onChange = () => {
      setIsMobile(mql.matches);
    };
    mql.addEventListener("change", onChange);
    setIsMobile(mql.matches);
    return () => mql.removeEventListener("change", onChange);
  }, []);

  return !!isMobile;
}
```



## Usage

Returns `true` when the viewport matches `(max-width: 63.999rem)` (~1024px). The first client
render resolves after mount; until then the returned value is `false`.

```tsx
import { useIsMobile } from "@/hooks/use-mobile";

export function Example() {
  const isMobile = useIsMobile();

  return <p>{isMobile ? "Mobile layout" : "Desktop layout"}</p>;
}
```

Useful for swapping layouts (for example sidebar sheet vs fixed rail) without CSS-only solutions.

