🍇

Next.js(TypeScript)にMUIを導入してみる

2023/02/27に公開
2

皆さんこんにちは。Sandyマンです。今回は、Next.js(TypeScript)の環境にMUI(旧Material-UI)を導入してみました。それでは早速やっていきましょう!

結論

MUIをインストールするやつ
npm install @mui/material @emotion/react @emotion/styled @emotion/server @mui/icons-material @fontsource/roboto

を実行してMUI関連のものをインストールする。(Emotionを使う場合)

インストールしたら、この公式テンプレートのsrcフォルダ内のcreateEmotionCache.ts, theme.tsとpagesフォルダ内の_app.tsxを丸パクリする。
https://github.com/mui/material-ui/tree/master/examples/material-next-ts/

コピペしたらこんな感じ
createEmotionCache.ts
import createCache from '@emotion/cache';

const isBrowser = typeof document !== 'undefined';

// On the client side, Create a meta tag at the top of the <head> and set it as insertionPoint.
// This assures that MUI styles are loaded first.
// It allows developers to easily override MUI styles with other styling solutions, like CSS modules.
export default function createEmotionCache() {
    let insertionPoint;

    if (isBrowser) {
        const emotionInsertionPoint = document.querySelector<HTMLMetaElement>('meta[name="emotion-insertion-point"]');
        insertionPoint = emotionInsertionPoint ?? undefined;
    }

    return createCache({ key: 'mui-style', insertionPoint });
}
theme.ts
import { Roboto } from '@next/font/google';
import { createTheme } from '@mui/material/styles';
import { red } from '@mui/material/colors';

export const roboto = Roboto({
    weight: ['300', '400', '500', '700'],
    subsets: ['latin'],
    display: 'swap',
    fallback: ['Helvetica', 'Arial', 'sans-serif']
});

// Create a theme instance.
const theme = createTheme({
    palette: {
        primary: {
            main: '#556cd6'
        },
        secondary: {
            main: '#19857b'
        },
        error: {
            main: red.A400
        }
    },
    typography: {
        fontFamily: roboto.style.fontFamily
    }
});

export default theme;
_app.tsx
import * as React from 'react';
import Head from 'next/head';
import { AppProps } from 'next/app';
import { ThemeProvider } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
import { CacheProvider, EmotionCache } from '@emotion/react';
import theme from '../theme';
import createEmotionCache from '../createEmotionCache';

// Client-side cache, shared for the whole session of the user in the browser.
const clientSideEmotionCache = createEmotionCache();

interface MyAppProps extends AppProps {
    emotionCache?: EmotionCache;
}

export default function MyApp(props: MyAppProps) {
    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>
    );
}

これで、てきとうなコンポーネントを作って動かしてみると、しっかりと表示されていると思います。テーマなどについてはこの辺に書いてあります。カスタマイズしながら使うといいですね。
https://mui.com/material-ui/customization/theming/

まとめ

こんな感じでやってみました。もし何か間違ってたりとかしたら教えてください!!それではさようならーーーーーーー!!

Discussion

YutaSaitoYutaSaito

参考になりました!ありがとうございます。

インポートのCLIで @emotion/server@mui/icons-material ここがつながっているようですので修正いただけると嬉しいです。

SandyマンSandyマン

今見たら繋がってました...!ご指摘ありがとうございます!修正させていただきます!