💬

Nextjs - Pages Router + TypeScript + MUI 最小プロジェクトで作る

2024/10/04に公開

Nextjs - Pages Router + TypeScript + MUI 最小プロジェクトで作る

概要

現状最新の環境下で構築する上での最小プロジェクト(サンプル)を共有。
公式のドキュメントを活用して導入しているので、ほぼ間違いはないと思う。

以下が現時点(2024.10)での最新バージョン

対象 バージョン
Nextjs v14.2.x
TypeScript v5.x.x
MUI v6.1.x

※ MUIは、旧Material-UIのこと

手順

1. プロジェクトを構築

npx create-next-app@latest --typescript

上記を入力後、下記の通りに選択肢が出るので従って選択する。

Ok to proceed? (y) ・・・ y
? What is your project named? › ・・・ プロジェクト名(小文字)
? Would you like to use ESLint? › No / Yes ・・・ Yes
? Would you like to use Tailwind CSS? › No / Yes ・・・ No
? Would you like to use `src/` directory? › No / Yes ・・・ No
? Would you like to use App Router? (recommended) › No / Yes ・・・ No
? Would you like to customize the default import alias (@/*)? › No / Yes ・・・ No

今回導入する際にはこのような選択肢だが、ルーティングの箇所以外については任意でもよい。
https://nextjs.org/docs/app/api-reference/cli/create-next-app

2. 必要なモジュールをインストールする

npm i @mui/material @mui/material-nextjs @emotion/cache @emotion/server @emotion/styled

公式のドキュメントよりも多いが、これでも最小限でありインストールしていないと必ずエラーとなる。

3. 各ファイルの編集

_app.tsx、_document.tsx、global.cssの3種のファイルが対象となる。
置き換えするのもバックアップ残すのも任意。

pages/_app.tsx

pages/_app.tsx
import "@/styles/globals.css";
import type { AppProps } from "next/app";
+ import { AppCacheProvider } from "@mui/material-nextjs/v14-pagesRouter";

- export default function App({ Component, pageProps }: AppProps) {
+ export default function App(props: AppProps) {
-   return <Component {...pageProps} />;
+   return (
+     <AppCacheProvider {...props}>
+       <props.Component />
+     </AppCacheProvider>
+   );
}

htmlをレンダリング時にMUIによって生成されたCSSを収集するためにAppCacheProviderを用いる。この時スタイル情報はbodyではなく、headerに記述される。

pages/_document.tsx

pages/_document.tsx
+ import {
+   DocumentHeadTags,
+   DocumentHeadTagsProps,
+   documentGetInitialProps,
+ } from '@mui/material-nextjs/v14-pagesRouter';
import { Html, Head, Main, NextScript } from "next/document";

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

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

公式のドキュメントではHtmlタグの言語指定が英語になっているが、日本で作成する分には日本語として設定するのが良い。

pages/index.tsx

pages/index.tsx
/* このサンプルでは内容の全て差し替えする */
import { Button, TextField, Container, Typography } from "@mui/material";

const Index = () => {
  return (
    <Container maxWidth="sm">
      <Typography variant="h4" component="h1" gutterBottom>
        Next.js & MUI Sample Page
      </Typography>
      <TextField
        label="Your Name"
        variant="outlined"
        fullWidth
        margin="normal"
      />
      <Button variant="contained" color="primary">
        Click Me
      </Button>
    </Container>
  );
}

export default Index;

最小で作成するため、タイトルとテキストフィールド・ボタンの3つのみ表示するUIを設計する。

styles/globals.css

styles/globals.css
/* このサンプルでは設定の必要ないので空ファイルにする */

これらの設定をすることでMUIが利用可能となる。
https://mui.com/material-ui/integrations/nextjs/

Discussion