Skip to content
+

Next.js integration

Learn how to use Material UI with Next.js

App Router

This section walks through the Material UI integration with the Next.js App Router, an evolution of the Pages Router, and, currently, the recommended way of building new Next.js applications starting from version 13.

Installing the dependencies

Start by ensuring that you already have @mui/material and next installed. Then, run one of the following commands to install the dependencies:

npm install @mui/material-nextjs @emotion/cache

Configuration

Inside app/layout.tsx, import the AppRouterCacheProvider and wrap all elements under the <body> with it:

+import { AppRouterCacheProvider } from '@mui/material-nextjs/v13-appRouter';
 // or `v1X-appRouter` if you are using Next.js v1X

 export default function RootLayout(props) {
   const { children } = props;
   return (
     <html lang="en">
       <body>
+        <AppRouterCacheProvider>{children}</AppRouterCacheProvider>
       </body>
     </html>
   );
 }

Using other styling solutions

If you are using a styling solution other than Emotion to customize Material UI components, set enableCssLayer: true in the options prop:

<AppRouterCacheProvider options={{ enableCssLayer: true }}>

This option ensures that the styles generated by Material UI will be wrapped in a CSS @layer mui rule, which is overridden by anonymous layer styles when using Material UI with CSS modules, Tailwind CSS, or even plain CSS without using @layer.

To learn more about it, see the MDN CSS layer documentation.

Pages Router

This section walks through the Material UI integration with the Next.js Pages Router, for both Server Side Rendering (SSR) and Static Site Generation (SSG).

Installing the dependencies

Start by ensuring that you already have @mui/material and next installed. Then, run one of the following commands to install the dependencies:

npm install @mui/material-nextjs @emotion/cache @emotion/server

Configuration

Inside the pages/_document.tsx file:

  • Import documentGetInitialProps and use it as the Document's getInitialProps.
  • Import DocumentHeadTags and render it inside the <Head>.
+import {
+  DocumentHeadTags,
+  documentGetInitialProps,
+} from '@mui/material-nextjs/v13-pagesRouter';
 // or `v1X-pagesRouter` if you are using Next.js v1X

 export default function MyDocument(props) {
   return (
     <Html lang="en">
       <Head>
+        <DocumentHeadTags {...props} />
         ...
       </Head>
       <body>
         <Main />
         <NextScript />
       </body>
     </Html>
   );
 }

+MyDocument.getInitialProps = async (ctx) => {
+  const finalProps = await documentGetInitialProps(ctx);
+  return finalProps;
+};

Then, inside pages/_app.tsx, import the AppCacheProvider component and render it as the root element:

+import { AppCacheProvider } from '@mui/material-nextjs/v13-pagesRouter';
 // Or `v1X-pages` if you are using Next.js v1X

 export default function MyApp(props) {
   return (
+    <AppCacheProvider {...props}>
       <Head>
         ...
       </Head>
       ...
+    </AppCacheProvider>
   );
 }

TypeScript

If you are using TypeScript, add DocumentHeadTagsProps to the Document's props interface:

+ import type { DocumentHeadTagsProps } from '@mui/material-nextjs/v13-pagesRouter';
  // or `v1X-pagesRouter` if you are using Next.js v1X

+ export default function MyDocument(props: DocumentProps & DocumentHeadTagsProps) {
   ...
 }