「Next.jsにMUIを入れたら、リロードの瞬間にスタイルが崩れてチラつく」「'use client'はどこに付ければいいのか分からない」——App Router時代のMUI導入で、ほぼ全員がぶつかる壁です。

先に結論です。

MUI公式の連携パッケージ@mui/material-nextjsが提供するAppRouterCacheProviderlayout.tsxに1つ入れるだけで、SSR(サーバーサイドレンダリング)時のスタイル問題は解決します。この記事では2026年7月時点の最新環境(Next.js 16 / MUI v9 / React 19)で、プロジェクト作成からテーマ設定までを5ステップで解説します。

私は実務でMUIベースの管理画面やサービスを複数構築してきました。ネット上にはPages Router前提の古い手順が今も大量に残っているので、「今の正解」だけを最短ルートでまとめます。

この記事でわかること
・Next.js 16(App Router)へのMUI v9導入の正しい手順
・AppRouterCacheProviderが必要な理由(SSRのスタイルちらつき対策)
・テーマ設定とRobotoフォントの組み込み方
・'use client'を付ける場所・付けない場所の判断基準

独学に限界を感じたら

プログラミング教室がおすすめ。挫折せず最短で実力を伸ばせます。

PR

今回の環境と全体像(2026年7月時点)

  • Next.js 16(App Router / Turbopackがデフォルト)
  • MUI(Material UI)v9 + Emotion(デフォルトのスタイルエンジン)
  • React 19 / TypeScript 5系

手順は次の5ステップです。①プロジェクト作成 → ②パッケージインストール → ③AppRouterCacheProvider設置 → ④動作確認 → ⑤テーマ設定。順番にいきましょう。公式ドキュメントも併記しておきます。

MUI: The React component library you always wantedMUI provides a simple, customizable, and accessible library of React components. Follow your own design system, or start with Material Design.mui.com

Next.js 16にMUI v9を導入する5ステップ

Step1:create-next-appでプロジェクトを作成する

npx create-next-app@latest my-app --typescript
cd my-app
npm run dev

質問はデフォルトのままEnterでOKです(App Routerが標準)。1点だけ注意:Tailwind CSSは「No」を選ぶのがおすすめです。MUIと共存はできますが、リセットCSSが競合しやすく、初学者が最初に組み合わせる構成としては難易度が上がります。

Step2:MUI v9と連携パッケージをインストールする

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

1行目はMUI本体とスタイルエンジンのEmotion。2行目が今回の主役、Next.js連携用の公式パッケージ@mui/material-nextjsとその依存の@emotion/cacheです。

古い記事には2行目が載っていないことが多く、それが「App Routerでチラつく」原因になります。アイコンを使うなら@mui/icons-materialも追加してください。

Step3:layout.tsxにAppRouterCacheProviderを設置する

import { AppRouterCacheProvider } from "@mui/material-nextjs/v15-appRouter";

export default function RootLayout({
  children,
}: Readonly<{ children: React.ReactNode }>) {
  return (
    <html lang="ja">
      <body>
        <AppRouterCacheProvider>{children}</AppRouterCacheProvider>
      </body>
    </html>
  );
}

なぜこれが必要なのか。App RouterのNext.jsはHTMLをストリーミング(分割送信)でクライアントに届けます。

AppRouterCacheProviderは、その過程でMUI(Emotion)が生成したCSSをサーバー側で収集し、HTMLと一緒に届ける役割を持ちます。

これがないと「HTMLだけ先に届いてスタイルが後から当たる」=一瞬素のHTMLが見えるチラつき(FOUC)が起きます。

importパスのv15-appRouterという名前は「対応するNext.jsのバージョン系統」を表すものです。

MUI v9+Next.js 16の組み合わせでも、公式ドキュメントが案内する現行パスはこのv15-appRouterです(2026年7月時点)。「v16がないから動かないのでは」と不安になる必要はありません。

Step4:ボタンを表示して動作確認する

import Button from "@mui/material/Button";

export default function Page() {
  return (
    <Button sx={{ m: 5 }} variant="outlined">
      Hello World
    </Button>
  );
}

ここで意外に感じるかもしれませんが、page.tsxに'use client'を書く必要はありません。MUIのコンポーネントは内部で'use client'が宣言済みなので、Server Componentからそのままimportして使えます。

http://localhost:3000/にアクセスして、下記のようにボタンが表示されれば成功です。

MUIのアウトラインボタンが表示された画面

Step5:テーマとリセットCSS(CssBaseline)を設定する

実務では必ずテーマを作ります。ポイントは2つ。createThemeを呼ぶファイルには'use client'が必要なことと、cssVariables: true有効にすることです(テーマ値がCSS変数として出力され、ダークモード切替時のチラつき防止にも効きます)。

"use client";

import { createTheme } from "@mui/material/styles";
import { orange } from "@mui/material/colors";

const theme = createTheme({
  cssVariables: true,
  palette: {
    primary: {
      main: orange[300],
    },
  },
  typography: {
    fontFamily: "var(--font-roboto)",
  },
  components: {
    // ボタンのデザインをグローバルに上書き
    MuiButton: {
      styleOverrides: {
        outlinedPrimary: {
          borderRadius: 0,
        },
      },
    },
  },
});

export default theme;

次に、layout.tsxでThemeProviderとCssBaseline(リセットCSS)を組み込みます。MUI標準のRobotoフォントはnext/font経由で読み込み、CSS変数でテーマに渡すのが公式推奨の形です。

import { AppRouterCacheProvider } from "@mui/material-nextjs/v15-appRouter";
import { ThemeProvider } from "@mui/material/styles";
import CssBaseline from "@mui/material/CssBaseline";
import { Roboto } from "next/font/google";
import theme from "../theme";

const roboto = Roboto({
  weight: ["300", "400", "500", "700"],
  subsets: ["latin"],
  variable: "--font-roboto",
});

export default function RootLayout({
  children,
}: Readonly<{ children: React.ReactNode }>) {
  return (
    <html lang="ja" className={roboto.variable}>
      <body>
        <AppRouterCacheProvider>
          <ThemeProvider theme={theme}>
            <CssBaseline />
            {children}
          </ThemeProvider>
        </AppRouterCacheProvider>
      </body>
    </html>
  );
}

再度アクセスして、ボタンにオレンジのテーマカラーと角丸なしのスタイルが当たっていれば完成です。

テーマが適用されたMUIボタンの表示例

'use client'はどこに付ける?判断基準まとめ

App Router×MUIで最も混乱しやすいのがここです。判断基準を表にまとめました。

場所'use client'理由
MUIコンポーネントをimportして表示するだけのページ不要MUI側で宣言済みのため
createThemeを書くファイル(theme.ts)必要テーマオブジェクトを関数ごとクライアントへ渡すため
onClickやuseStateを書く自作コンポーネント必要通常のApp Routerのルールどおり
layout.tsx本体不要Provider類はimportするだけでよい

現場でよくある失敗は、エラーに驚いてページ全体に'use client'を付けて回るパターンです。動きはしますが、Server Componentの利点(バンドル削減・サーバー側データ取得)を全部捨てることになります。

プロのコツは「インタラクションが発生する末端のコンポーネントだけをクライアント化する」こと。設計の考え方はNext.jsのディレクトリ設計で詳しく解説しています。

初心者がハマりやすいポイント3つ

1. AppRouterCacheProviderを入れ忘れる

開発中は気づきにくく、本番ビルドで初回表示が一瞬崩れて発覚します。症状が「たまにチラつく」なので原因特定に時間がかかりがち。

MUI導入と同時に必ずセットで入れると覚えてください。CSSの詳細度で他のスタイルと競合する場合は、options={{ enableCssLayer: true }}を渡すとMUIのスタイルが@layer muiに包まれ、上書きしやすくなります。

2. Pages Router向けの古い手順を混ぜてしまう

「_app.tsx」「_document.tsx」が出てくる解説はPages Router向けです。App Routerにそれらのファイルは存在しません。検索結果の日付とルーター種別は必ず確認しましょう。Next.js 15→16での変更点はNext.js 16移行ガイドにまとめています。

3. importパスの「v15」を見て古いと勘違いする

前述のとおりv15-appRouterが現行の公式案内パスです(2026年7月時点)。むしろ古い記事にあるv13-appRouter等を使い続けている方が問題なので、既存プロジェクトのアップグレード時はここも見直してください。

まとめ:MUIが使えると開発速度が一段上がる

  • インストールは@mui/material本体+@mui/material-nextjsの2段構え
  • layout.tsxにAppRouterCacheProviderを設置してSSRのチラつきを防ぐ
  • theme.tsは'use client'+cssVariables: true、フォントはnext/font経由のRoboto
  • 'use client'は「テーマ定義」と「インタラクションを書く末端」だけに付ける

MUIのようなUIライブラリを「正しくセットアップして使える」スキルは、管理画面系の案件を中心に今も需要が根強く、ポートフォリオの見栄えと開発速度を同時に上げてくれます。独学でここまで組めたなら、次は実務です。

React/Next.jsの実務経験が積める現場は、転職エージェントやフリーランスエージェントに複数登録して比較すると見つかりやすくなります。「MUI(Material UI)使用経験あり」は職務経歴書で普通にアピール材料になりますよ。

Vite+ReactでMUIを使いたい人はReactでのMUI環境構築、UIが組めたら次はテストとしてNext.js×Jest入門もどうぞ。

よくある質問(FAQ)

Q. MUIとTailwind CSSはどちらを学ぶべきですか?

目的が違います。MUIは「完成品のコンポーネント集」で管理画面・業務システムに強く、Tailwindは「スタイルを速く書く道具」でデザイン自由度の高いサイトに強い。求人ではどちらも頻出なので、片方を深く使えるようになってからもう片方に触れるのがおすすめです。

Q. sx propとstyled、どちらでスタイルを書くべきですか?

単発の微調整はsx、再利用するコンポーネントはstyledやテーマのstyleOverridesが定石です。現場レビューで指摘されがちなのは、同じsxを何ヶ所もコピペするパターン。2回以上書いたら共通化を検討しましょう。

Q. ダークモード対応はどうすればいいですか?

createThemeのcolorSchemesでlight/dark両方のパレットを定義する方式が現行の推奨です。cssVariables: trueと組み合わせると、SSR時のモード判定ズレによるチラつきを避けやすくなります。まずは本記事の構成で土台を作ってから追加するのがスムーズです。

あわせて読みたい関連記事

React+MUI v9環境構築|Viteで最短セットアップ【2026年】CRA前提のMUI入門記事はもう再現できません。2026年の正解はVite + MUI v9(v8は欠番)です。インストールからCssBaseline、createThemeでのカスタムテーマ、ハマりやすい落とし穴まで、コピペで動く最新のReact + MUI環境構築手順を現役エンジニアが解説します。frontendlab.magicgifted.com Next.js 16移行ガイド|破壊的変更と新機能まとめ【2026】Turbopackが標準に、middlewareはproxyへ、paramsの同期アクセスは完全廃止——Next.js 16の破壊的変更と新機能を公式アップグレードガイドに沿って整理。codemodで自動化できる部分と手作業が必要な部分を切り分け、コピペで使える移行手順を解説します。frontendlab.magicgifted.com Next.js 16×Jest導入ガイド|App Router対応の最新設定【2026年】Next.js 16のApp RouterでJestを動かす最新手順を解説。next/jestを使えばts-jestは不要で、TypeScriptもそのまま動きます。動くテスト例3つ、Server Componentテストの注意点、Vitestとの比較まで2026年基準でまとめました。frontendlab.magicgifted.com