Open In App

How to use Material-UI with Next.js ?

Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will learn some additional necessary steps to be performed to integrate Material-UI with the Next.js project.

First Let’s start by creating a Next.js project.

Create Next.js project: Run the following command in the terminal

npx create-next-app gfg-next-mui

Project Structure: It will look like this.

Project Structure

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

Now follow the below steps:

Step 1: Create a custom file /pages/_document.js and add the following code to it.

_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 (
            <Html lang="en">
                <Head>
                    {/* PWA primary color */}
                    <meta name="theme-color" 
                        content={theme.palette.primary.main} />
                    <link rel="shortcut icon" 
                        href="/static/favicon.ico" />
                    <link
                        rel="stylesheet"
                        href=
                    />
{/* Inject MUI styles first to match with the prepend: true configuration. */}
                    {this.props.emotionStyleTags}
                </Head>
                <body>
                    <Main />
                    <NextScript />
                </body>
            </Html>
        );
    }
}
  
// `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 
      
    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 2: Create an src folder, add theme.js and createEmotionCache.js files as below

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;


createEmotionCache.js




import createCache from '@emotion/cache';
  
export default function createEmotionCache() {
    return createCache({ key: 'css', prepend: true });
}


Step 3: Update the file /pages/_app.js with the below code

_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 4: Update the file /pages/index.js with the below code

index.js




import Head from "next/head";
import styles from "../styles/Home.module.css";
  
export default function Home() {
    return (
        <div className={styles.container}>
            <Head>
                <title>Create Next App</title>
                <link rel="icon" href="/favicon.ico" />
            </Head>
  
            <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:



Last Updated : 05 Jan, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads