Using MaterialUI with Next.js (original) (raw)
Using Material-UI with Next.js
Last Updated : 11 Mar, 2026
Material-UI (MUI) is a popular React UI framework that provides ready-made components following Google’s Material Design. It integrates well with Next.js to build responsive, modern web interfaces quickly.
- Provides pre-built UI components like buttons, cards, dialogs, and navigation bars.
- Works smoothly with Next.js SSR (Server-Side Rendering) for better performance and SEO.
- Supports custom themes and styling to easily design consistent user interfaces.
Approach
To use the Material-UI with Next.js
- Wrap the entire application with ThemeProvider to apply consistent theming across all components.
- Use Material-UI components in Next.js pages to build responsive and modern user interfaces.
- Ensure server-side rendering support using Emotion styling for optimized performance and consistent styling.
First Let's start by creating a Next.js project.
**Steps to Integrate Material UI with Next.js
**Step 1: Initialize a nwe Next.js project using the following command:
npx create-next-app gfg-next-mui
**Step 2: Move to the Project directory
cd gfg-next-mui
**Step 3: Install Material-UI
To install the dependencies and save them in your package.json file, run:
npm install @mui/material @emotion/react @emotion/styled @emotion/server
**Project Structure
It will look like this.

The updated dependencies in the package.json file are:
"dependencies": { "@emotion/react": "^11.13.0", "@emotion/server": "^11.11.0", "@emotion/styled": "^11.13.0", "@mui/material": "^5.16.5", "next": "14.2.4", "react": "^18", "react-dom": "^18" }
**Step 4: Modify the _document.js file. Configure the next app for server-side rendering using the Material UI and emotion library.
JavaScript ``
// pages/_document.js
import * as React from 'react'; import Document, { Html, Head, Main, NextScript } from 'next/document'; import createEmotionServer from '@emotion/server/create-instance'; import theme from '../src/theme'; import createEmotionCache from '../src/createEmotionCache';
export default class MyDocument extends Document {
render() {
return (
{/* PWA primary color /}
{/ Inject MUI styles first to match with the prepend: true configuration. */}
{this.props.emotionStyleTags}
// getInitialProps belongs to _document (instead of _app),
// it's compatible with static-site generation (SSG).
MyDocument.getInitialProps = async (ctx) => {
const originalRenderPage = ctx.renderPage;
// You can consider sharing the same emotion cache between
// all the SSR requests to speed up performance.
// However, be aware that it can have global side effects.const cache = createEmotionCache(); const { extractCriticalToChunks } = createEmotionServer(cache);
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) =>
function EnhanceApp(props) {
return <App emotionCache={cache} {...props} />;
},
});
const initialProps = await Document.getInitialProps(ctx);
// This is important. It prevents emotion to render invalid HTML.
// See // https://github.com/mui-org/material-ui/issues/26561#issuecomment-855286153
const emotionStyles = extractCriticalToChunks(initialProps.html);
const emotionStyleTags = emotionStyles.styles.map((style) => (
<style
data-emotion={`${style.key} ${style.ids.join(' ')}`}
key={style.key}
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: style.css }}
/>
));
return {
...initialProps,
emotionStyleTags,
};};
``
**Step 5: Define Material-UI theme with custom primary, secondary, and error colors using createTheme from @mui/material/styles.
Create an _src folder, add _theme.js and _createEmotionCache.js files as below
JavaScript `
// Filename - src/theme.js
import { createTheme } from "@mui/material/styles"; import { red } from "@mui/material/colors";
// Create a theme instance. const theme = createTheme({ palette: { primary: { main: "#556cd6", }, secondary: { main: "#19857b", }, error: { main: red.A400, }, }, });
export default theme;
JavaScript
// Filename - src/createEmotionCache.js
import createCache from '@emotion/cache';
export default function createEmotionCache() { return createCache({ key: 'css', prepend: true }); }
`
**Step 5: Update the file /pages/_app.js with the below code
JavaScript `
// Filename - pages/_app.js
import * as React from "react"; import PropTypes from "prop-types"; import Head from "next/head"; import { ThemeProvider } from "@mui/material/styles"; import CssBaseline from "@mui/material/CssBaseline"; import { CacheProvider } from "@emotion/react"; import theme from "../src/theme"; import createEmotionCache from "../src/createEmotionCache";
// Client-side cache shared for the whole session // of the user in the browser.
const clientSideEmotionCache = createEmotionCache();
export default function MyApp(props) { const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
return (
<CacheProvider value={emotionCache}>
<Head>
<meta
name="viewport"
content="initial-scale=1,
width=device-width" />
</Head>
<ThemeProvider theme={theme}>
{/* CssBaseline kickstart an elegant,
consistent, and simple baseline to
build upon. */}
<CssBaseline />
<Component {...pageProps} />
</ThemeProvider>
</CacheProvider>
);}
MyApp.propTypes = { Component: PropTypes.elementType.isRequired, emotionCache: PropTypes.object, pageProps: PropTypes.object.isRequired, };
`
**Step 6: Update the Home Component in _/pages/index.js with the below code.
JavaScript `
// pages/inde.js
import Head from "next/head"; import styles from "../styles/Home.module.css";
export default function Home() { return (
<main className={styles.main}>
<h1 className={styles.title}>
Welcome to <a href="https://nextjs.org/">
Next.js!</a> integrated with{" "}
<a href="https://mui.com/">Material-UI!</a>
</h1>
<p className={styles.description}>
Get started by editing{" "}
<code className={styles.code}>
pages/index.js</code>
</p>
</main>
</div>
);}
`
**Steps to run the application: To run the app, type the following command in the terminal.
npm run dev
**Output:
