--- productId: material-ui title: Media queries in React for responsive design githubLabel: 'hook: useMediaQuery' githubSource: packages/mui-material/src/useMediaQuery --- # useMediaQuery
This React hook listens for matches to a CSS media query. It allows the rendering of components based on whether the query matches or not.
Some of the key features: - ⚛️ It has an idiomatic React API. - 🚀 It's performant, it observes the document to detect when its media queries change, instead of polling the values periodically. - 📦 [1.1 kB gzipped](https://bundlephobia.com/package/@mui/material). - 🤖 It supports server-side rendering. {{"component": "@mui/docs/ComponentLinkHeader", "design": false}} ## Basic media query You should provide a media query to the first argument of the hook. The media query string can be any valid CSS media query, for example [`'(prefers-color-scheme: dark)'`](/material-ui/customization/dark-mode/#system-preference). {{"demo": "SimpleMediaQuery.js", "defaultCodeOpen": true}} :::warning Using the query `'print'` to modify a document for printing is not supported, as changes made in re-rendering may not be accurately reflected. You can use the `sx` prop's `displayPrint` field for this purpose instead. See [MUI System—Display in print](/system/display/#display-in-print) for more details. ::: ## Using breakpoint helpers You can use Material UI's [breakpoint helpers](/material-ui/customization/breakpoints/) as follows: ```jsx import { useTheme } from '@mui/material/styles'; import useMediaQuery from '@mui/material/useMediaQuery'; function MyComponent() { const theme = useTheme(); const matches = useMediaQuery(theme.breakpoints.up('sm')); return {`theme.breakpoints.up('sm') matches: ${matches}`}; } ``` {{"demo": "ThemeHelper.js", "defaultCodeOpen": false}} Alternatively, you can use a callback function, accepting the theme as a first argument: ```jsx import useMediaQuery from '@mui/material/useMediaQuery'; function MyComponent() { const matches = useMediaQuery((theme) => theme.breakpoints.up('sm')); return {`theme.breakpoints.up('sm') matches: ${matches}`}; } ``` ⚠️ There is **no default** theme support, you have to inject it in a parent theme provider. ## Using JavaScript syntax You can use [json2mq](https://github.com/akiran/json2mq) to generate media query string from a JavaScript object. {{"demo": "JavaScriptMedia.js", "defaultCodeOpen": true}} ## Testing You need an implementation of [matchMedia](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia) in your test environment. For instance, [jsdom doesn't support it yet](https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom). You should polyfill it. Using [css-mediaquery](https://github.com/ericf/css-mediaquery) to emulate it is recommended. ```js import mediaQuery from 'css-mediaquery'; function createMatchMedia(width) { return (query) => ({ matches: mediaQuery.match(query, { width, }), addEventListener: () => {}, removeEventListener: () => {}, }); } describe('MyTests', () => { beforeAll(() => { window.matchMedia = createMatchMedia(window.innerWidth); }); }); ``` ## Client-side only rendering To perform the server-side hydration, the hook needs to render twice. A first time with `defaultMatches`, the value of the server, and a second time with the resolved value. This double pass rendering cycle comes with a drawback: it's slower. You can set the `noSsr` option to `true` if you use the returned value **only** client-side. ```js const matches = useMediaQuery('(min-width:600px)', { noSsr: true }); ``` or it can turn it on globally with the theme: ```js const theme = createTheme({ components: { MuiUseMediaQuery: { defaultProps: { noSsr: true, }, }, }, }); ``` :::info Note that `noSsr` has no effects when using the `createRoot()` API (the client-side only API introduced in React 18). ::: ## Server-side rendering :::warning Server-side rendering and client-side media queries are fundamentally at odds. Be aware of the tradeoff. The support can only be partial. ::: Try relying on client-side CSS media queries first. For instance, you could use: - [`