# How to Integrate Material-UI with Next.js App Router Using @mui/material-nextjs

> Seamlessly integrate Material-UI with Next.js App Router. Learn how to use AppRouterCacheProvider from mui material nextjs to stream server-side CSS efficiently.

- Repository: [MUI/material-ui](https://github.com/mui/material-ui)
- Tags: how-to-guide
- Published: 2026-02-26

---

**Use the `AppRouterCacheProvider` component from `@mui/material-nextjs` to create an Emotion cache that collects server-side CSS and streams style tags into the HTML response.**

Material-UI provides a dedicated integration package `@mui/material-nextjs` that streamlines server-side rendering in Next.js 13+ applications using the App Router. This package exports the `AppRouterCacheProvider` component, which manages Emotion cache insertion during streaming SSR. According to the Material-UI source code, the provider wraps your application tree to ensure styles are correctly generated on the server and hydrated on the client.

## Installation and Setup

First, install the integration package alongside Emotion cache (required peer dependency):

```bash
npm install @mui/material-nextjs @emotion/cache

```

Or using Yarn or pnpm:

```bash
yarn add @mui/material-nextjs @emotion/cache

# or

pnpm add @mui/material-nextjs @emotion/cache

```

## Configuring the Root Layout

Wrap your application root with `AppRouterCacheProvider` in your [`app/layout.tsx`](https://github.com/mui/material-ui/blob/main/app/layout.tsx) file. Import the provider from the version-specific entry point that matches your Next.js version (e.g., `v15-appRouter` for Next.js 15).

```tsx
import { AppRouterCacheProvider } from '@mui/material-nextjs/v15-appRouter';

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

```

## How AppRouterCacheProvider Works

The integration relies on a thin wrapper around Emotion's caching system implemented in [`packages/mui-material-nextjs/src/v13-appRouter/appRouterV13.tsx`](https://github.com/mui/material-ui/blob/main/packages/mui-material-nextjs/src/v13-appRouter/appRouterV13.tsx). Understanding this architecture helps debug styling issues in complex applications.

### Emotion Cache Architecture

The provider initializes an Emotion cache using `createCache` with a default key of **`mui`**. In the source code, the cache is configured with `cache.compat = true` to ensure generated class names match the classic Emotion format used by Material-UI components. This cache is then supplied to the React tree via Emotion's `CacheProvider`.

### Server-Side Style Collection

During server-side rendering, the provider wraps the cache's `insert` method to record every style that is rendered. When Next.js calls `useServerInsertedHTML` (imported via the shim in `packages/mui-material-nextjs/src/v13-appRouter/nextNavigation.cjs`), the provider flushes the recorded styles and returns `<style>` elements that are injected into the streamed HTML. This mechanism ensures critical CSS arrives with the initial HTML payload.

### CSS Cascade Layer Support

When the `options.enableCssLayer` flag is set to `true`, each style block is wrapped in `@layer mui { … }`. This allows developers to control style precedence when mixing Material-UI with Tailwind CSS, CSS Modules, or other styling solutions that utilize cascade layers.

## Advanced Configuration

### Enabling CSS Layers

To isolate Material-UI styles within a cascade layer—useful for resolving specificity conflicts with other CSS-in-JS solutions—pass the `enableCssLayer` option:

```tsx
import { AppRouterCacheProvider } from '@mui/material-nextjs/v15-appRouter';

<AppRouterCacheProvider options={{ enableCssLayer: true, key: 'mui' }}>
  {children}
</AppRouterCacheProvider>

```

### Font Optimization with Next.js

Combine the cache provider with Next.js 13+ font optimization by passing the font variable to your theme:

```tsx
'use client';
import { createTheme } from '@mui/material/styles';
import { ThemeProvider } from '@mui/material';
import { Roboto } from 'next/font/google';
import { AppRouterCacheProvider } from '@mui/material-nextjs/v15-appRouter';

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

const theme = createTheme({
  typography: { fontFamily: 'var(--font-roboto)' },
});

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

```

## Summary

- **`@mui/material-nextjs`** provides `AppRouterCacheProvider` for seamless Material-UI integration with Next.js App Router.
- The provider creates an Emotion cache in [`packages/mui-material-nextjs/src/v13-appRouter/appRouterV13.tsx`](https://github.com/mui/material-ui/blob/main/packages/mui-material-nextjs/src/v13-appRouter/appRouterV13.tsx) that tracks server-rendered styles.
- It uses `useServerInsertedHTML` from Next.js (via `nextNavigation.cjs`) to stream style tags into the HTML response.
- Enable **`options.enableCssLayer`** to wrap styles in `@layer mui` for cascade control with Tailwind or CSS Modules.
- Install alongside **`@emotion/cache`** as a peer dependency.

## Frequently Asked Questions

### What is the difference between @mui/material-nextjs and @emotion/cache?

`@mui/material-nextjs` is a thin integration wrapper that configures `@emotion/cache` specifically for Next.js App Router streaming SSR. While `@emotion/cache` provides the underlying caching mechanism, the Material-UI package handles the complex coordination between Emotion's style insertion and Next.js's `useServerInsertedHTML` hook, ensuring styles are correctly collected and injected during server-side rendering.

### Why do I need to use a specific version import like v15-appRouter?

The versioned imports (e.g., `v13-appRouter`, `v15-appRouter`) correspond to Next.js major versions and ensure compatibility with specific App Router APIs. The underlying implementation in [`packages/mui-material-nextjs/src/v13-appRouter/appRouterV13.tsx`](https://github.com/mui/material-ui/blob/main/packages/mui-material-nextjs/src/v13-appRouter/appRouterV13.tsx) remains consistent, but the entry points handle different Next.js dependency requirements and prevent client/server bundle mismatches.

### How does enableCssLayer resolve style conflicts with Tailwind CSS?

When `enableCssLayer` is set to `true`, the provider wraps all Material-UI styles in `@layer mui { ... }`. This places MUI styles within a named cascade layer with lower priority than unlayered styles (like Tailwind's utility classes), allowing Tailwind utilities to override Material-UI component styles without requiring excessive specificity or `!important` flags.

### Can I use a custom Emotion cache key with AppRouterCacheProvider?

Yes. While the default cache key is **`mui`**, you can override it via the `options.key` property. This is useful when running multiple Emotion instances or when integrating with other libraries that also use Emotion, though you should ensure the key matches across server and client to prevent hydration mismatches.