diff --git a/examples/material-ui-nextjs-pages-router-ts/package.json b/examples/material-ui-nextjs-pages-router-ts/package.json
index 00a91c1360664b..1b522774bc1e53 100644
--- a/examples/material-ui-nextjs-pages-router-ts/package.json
+++ b/examples/material-ui-nextjs-pages-router-ts/package.json
@@ -16,6 +16,7 @@
"@emotion/styled": "latest",
"@mui/icons-material": "latest",
"@mui/material": "latest",
+ "@mui/material-nextjs": "latest",
"next": "latest",
"react": "latest",
"react-dom": "latest"
diff --git a/examples/material-ui-nextjs-pages-router-ts/pages/_app.tsx b/examples/material-ui-nextjs-pages-router-ts/pages/_app.tsx
index f41dbacff76eaf..9758b017cebfad 100644
--- a/examples/material-ui-nextjs-pages-router-ts/pages/_app.tsx
+++ b/examples/material-ui-nextjs-pages-router-ts/pages/_app.tsx
@@ -1,23 +1,15 @@
import * as React from 'react';
import Head from 'next/head';
import { AppProps } from 'next/app';
+import { AppCacheProvider } from '@mui/material-nextjs/v14-pagesRouter';
import { ThemeProvider } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
-import { CacheProvider, EmotionCache } 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 interface MyAppProps extends AppProps {
- emotionCache?: EmotionCache;
-}
-
-export default function MyApp(props: MyAppProps) {
- const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
+export default function MyApp(props: AppProps) {
+ const { Component, pageProps } = props;
return (
-
+
@@ -26,6 +18,6 @@ export default function MyApp(props: MyAppProps) {
-
+
);
}
diff --git a/examples/material-ui-nextjs-pages-router-ts/pages/_document.tsx b/examples/material-ui-nextjs-pages-router-ts/pages/_document.tsx
index e61175113c0151..8e42b2b7ecabd0 100644
--- a/examples/material-ui-nextjs-pages-router-ts/pages/_document.tsx
+++ b/examples/material-ui-nextjs-pages-router-ts/pages/_document.tsx
@@ -1,23 +1,9 @@
import * as React from 'react';
-import Document, {
- Html,
- Head,
- Main,
- NextScript,
- DocumentProps,
- DocumentContext,
-} from 'next/document';
-import createEmotionServer from '@emotion/server/create-instance';
-import { AppType } from 'next/app';
+import { Html, Head, Main, NextScript, DocumentProps } from 'next/document';
+import { DocumentHeadTags, documentGetInitialProps } from '@mui/material-nextjs/v14-pagesRouter';
import theme, { roboto } from '../src/theme';
-import createEmotionCache from '../src/createEmotionCache';
-import { MyAppProps } from './_app';
-interface MyDocumentProps extends DocumentProps {
- emotionStyleTags: JSX.Element[];
-}
-
-export default function MyDocument({ emotionStyleTags }: MyDocumentProps) {
+export default function MyDocument(props: DocumentProps) {
return (
@@ -25,7 +11,7 @@ export default function MyDocument({ emotionStyleTags }: MyDocumentProps) {
- {emotionStyleTags}
+
@@ -35,61 +21,4 @@ export default function MyDocument({ emotionStyleTags }: MyDocumentProps) {
);
}
-// `getInitialProps` belongs to `_document` (instead of `_app`),
-// it's compatible with static-site generation (SSG).
-MyDocument.getInitialProps = async (ctx: DocumentContext) => {
- // Resolution order
- //
- // On the server:
- // 1. app.getInitialProps
- // 2. page.getInitialProps
- // 3. document.getInitialProps
- // 4. app.render
- // 5. page.render
- // 6. document.render
- //
- // On the server with error:
- // 1. document.getInitialProps
- // 2. app.render
- // 3. page.render
- // 4. document.render
- //
- // On the client
- // 1. app.getInitialProps
- // 2. page.getInitialProps
- // 3. app.render
- // 4. page.render
-
- 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: React.ComponentType & MyAppProps>) =>
- function EnhanceApp(props) {
- return ;
- },
- });
-
- const initialProps = await Document.getInitialProps(ctx);
- // This is important. It prevents Emotion to render invalid HTML.
- // See https://github.com/mui/material-ui/issues/26561#issuecomment-855286153
- const emotionStyles = extractCriticalToChunks(initialProps.html);
- const emotionStyleTags = emotionStyles.styles.map((style) => (
-
- ));
-
- return {
- ...initialProps,
- emotionStyleTags,
- };
-};
+MyDocument.getInitialProps = documentGetInitialProps;
diff --git a/examples/material-ui-nextjs-pages-router-ts/src/createEmotionCache.ts b/examples/material-ui-nextjs-pages-router-ts/src/createEmotionCache.ts
deleted file mode 100644
index f64ea60f6c2902..00000000000000
--- a/examples/material-ui-nextjs-pages-router-ts/src/createEmotionCache.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import createCache from '@emotion/cache';
-
-const isBrowser = typeof document !== 'undefined';
-
-// On the client side, Create a meta tag at the top of the 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(
- 'meta[name="emotion-insertion-point"]',
- );
- insertionPoint = emotionInsertionPoint ?? undefined;
- }
-
- return createCache({ key: 'mui-style', insertionPoint });
-}
diff --git a/examples/material-ui-nextjs-pages-router/package.json b/examples/material-ui-nextjs-pages-router/package.json
index fada50ba0e6321..a246af69d94433 100644
--- a/examples/material-ui-nextjs-pages-router/package.json
+++ b/examples/material-ui-nextjs-pages-router/package.json
@@ -16,6 +16,7 @@
"@emotion/styled": "latest",
"@mui/icons-material": "latest",
"@mui/material": "latest",
+ "@mui/material-nextjs": "latest",
"next": "latest",
"prop-types": "latest",
"react": "latest",
diff --git a/examples/material-ui-nextjs-pages-router/pages/_app.js b/examples/material-ui-nextjs-pages-router/pages/_app.js
index 31a9f91e9a96ad..f7d8edc0714097 100644
--- a/examples/material-ui-nextjs-pages-router/pages/_app.js
+++ b/examples/material-ui-nextjs-pages-router/pages/_app.js
@@ -1,20 +1,16 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import Head from 'next/head';
+import { AppCacheProvider } from '@mui/material-nextjs/v14-pagesRouter';
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;
+ const { Component, pageProps } = props;
return (
-
+
@@ -23,12 +19,11 @@ export default function MyApp(props) {
-
+
);
}
MyApp.propTypes = {
Component: PropTypes.elementType.isRequired,
- emotionCache: PropTypes.object,
pageProps: PropTypes.object.isRequired,
};
diff --git a/examples/material-ui-nextjs-pages-router/pages/_document.js b/examples/material-ui-nextjs-pages-router/pages/_document.js
index fd589546a63d6d..58a3c38deecacf 100644
--- a/examples/material-ui-nextjs-pages-router/pages/_document.js
+++ b/examples/material-ui-nextjs-pages-router/pages/_document.js
@@ -1,13 +1,9 @@
import * as React from 'react';
-import PropTypes from 'prop-types';
-import Document, { Html, Head, Main, NextScript } from 'next/document';
-import createEmotionServer from '@emotion/server/create-instance';
+import { Html, Head, Main, NextScript } from 'next/document';
+import { DocumentHeadTags, documentGetInitialProps } from '@mui/material-nextjs/v14-pagesRouter';
import theme from '../src/theme';
-import createEmotionCache from '../src/createEmotionCache';
export default function MyDocument(props) {
- const { emotionStyleTags } = props;
-
return (
@@ -15,7 +11,7 @@ export default function MyDocument(props) {
- {emotionStyleTags}
+
@@ -25,65 +21,4 @@ export default function MyDocument(props) {
);
}
-// `getInitialProps` belongs to `_document` (instead of `_app`),
-// it's compatible with static-site generation (SSG).
-MyDocument.getInitialProps = async (ctx) => {
- // Resolution order
- //
- // On the server:
- // 1. app.getInitialProps
- // 2. page.getInitialProps
- // 3. document.getInitialProps
- // 4. app.render
- // 5. page.render
- // 6. document.render
- //
- // On the server with error:
- // 1. document.getInitialProps
- // 2. app.render
- // 3. page.render
- // 4. document.render
- //
- // On the client
- // 1. app.getInitialProps
- // 2. page.getInitialProps
- // 3. app.render
- // 4. page.render
-
- 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 ;
- },
- });
-
- const initialProps = await Document.getInitialProps(ctx);
- // This is important. It prevents Emotion to render invalid HTML.
- // See https://github.com/mui/material-ui/issues/26561#issuecomment-855286153
- const emotionStyles = extractCriticalToChunks(initialProps.html);
- const emotionStyleTags = emotionStyles.styles.map((style) => (
-
- ));
-
- return {
- ...initialProps,
- emotionStyleTags,
- };
-};
-
-MyDocument.propTypes = {
- emotionStyleTags: PropTypes.array.isRequired,
-};
+MyDocument.getInitialProps = documentGetInitialProps;
diff --git a/examples/material-ui-nextjs-pages-router/src/createEmotionCache.js b/examples/material-ui-nextjs-pages-router/src/createEmotionCache.js
deleted file mode 100644
index a1f11107d2ed06..00000000000000
--- a/examples/material-ui-nextjs-pages-router/src/createEmotionCache.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import createCache from '@emotion/cache';
-
-const isBrowser = typeof document !== 'undefined';
-
-// On the client side, Create a meta tag at the top of the 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('meta[name="emotion-insertion-point"]');
- insertionPoint = emotionInsertionPoint ?? undefined;
- }
-
- return createCache({ key: 'mui-style', insertionPoint });
-}
diff --git a/examples/material-ui-nextjs-ts-v4-v5-migration/package.json b/examples/material-ui-nextjs-ts-v4-v5-migration/package.json
index db216a74f29735..a67c1d3d9aebd5 100644
--- a/examples/material-ui-nextjs-ts-v4-v5-migration/package.json
+++ b/examples/material-ui-nextjs-ts-v4-v5-migration/package.json
@@ -16,6 +16,7 @@
"@emotion/styled": "latest",
"@mui/icons-material": "latest",
"@mui/material": "latest",
+ "@mui/material-nextjs": "latest",
"@mui/styles": "latest",
"autoprefixer": "latest",
"clean-css": "latest",
diff --git a/examples/material-ui-nextjs-ts-v4-v5-migration/pages/_app.tsx b/examples/material-ui-nextjs-ts-v4-v5-migration/pages/_app.tsx
index 6f36919bab5a6d..f58344c470fa0c 100644
--- a/examples/material-ui-nextjs-ts-v4-v5-migration/pages/_app.tsx
+++ b/examples/material-ui-nextjs-ts-v4-v5-migration/pages/_app.tsx
@@ -1,21 +1,13 @@
import * as React from 'react';
import Head from 'next/head';
import { AppProps } from 'next/app';
+import { AppCacheProvider } from '@mui/material-nextjs/v14-pagesRouter';
import { ThemeProvider } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
-import { CacheProvider, EmotionCache } 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 interface MyAppProps extends AppProps {
- emotionCache?: EmotionCache;
-}
-
-export default function MyApp(props: MyAppProps) {
- const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
+export default function MyApp(props: AppProps) {
+ const { Component, pageProps } = props;
React.useEffect(() => {
// Remove the server-side injected CSS.
@@ -26,7 +18,7 @@ export default function MyApp(props: MyAppProps) {
}, []);
return (
-
+
@@ -35,6 +27,6 @@ export default function MyApp(props: MyAppProps) {
-
+
);
}
diff --git a/examples/material-ui-nextjs-ts-v4-v5-migration/pages/_document.tsx b/examples/material-ui-nextjs-ts-v4-v5-migration/pages/_document.tsx
index 23aa7cc2cc818c..eefacf6a98d8b9 100644
--- a/examples/material-ui-nextjs-ts-v4-v5-migration/pages/_document.tsx
+++ b/examples/material-ui-nextjs-ts-v4-v5-migration/pages/_document.tsx
@@ -1,24 +1,19 @@
import * as React from 'react';
-import Document, {
+import {
Html,
Head,
Main,
NextScript,
DocumentProps,
+ DocumentInitialProps,
DocumentContext,
} from 'next/document';
-import createEmotionServer from '@emotion/server/create-instance';
-import { AppType } from 'next/app';
+import { AppProps } from 'next/app';
+import { DocumentHeadTags, documentGetInitialProps } from '@mui/material-nextjs/v14-pagesRouter';
import { ServerStyleSheets as JSSServerStyleSheets } from '@mui/styles';
import theme from '../src/theme';
-import createEmotionCache from '../src/createEmotionCache';
-import { MyAppProps } from './_app';
-interface MyDocumentProps extends DocumentProps {
- emotionStyleTags: JSX.Element[];
-}
-
-export default function MyDocument({ emotionStyleTags }: MyDocumentProps) {
+export default function MyDocument(props: DocumentProps) {
return (
@@ -26,7 +21,7 @@ export default function MyDocument({ emotionStyleTags }: MyDocumentProps) {
{/* Inject MUI styles first to match with the prepend: true configuration. */}
- {emotionStyleTags}
+
@@ -56,82 +51,43 @@ if (process.env.NODE_ENV === 'production') {
cleanCSS = new CleanCSS();
}
-// `getInitialProps` belongs to `_document` (instead of `_app`),
-// it's compatible with static-site generation (SSG).
MyDocument.getInitialProps = async (ctx: DocumentContext) => {
- // Resolution order
- //
- // On the server:
- // 1. app.getInitialProps
- // 2. page.getInitialProps
- // 3. document.getInitialProps
- // 4. app.render
- // 5. page.render
- // 6. document.render
- //
- // On the server with error:
- // 1. document.getInitialProps
- // 2. app.render
- // 3. page.render
- // 4. document.render
- //
- // On the client
- // 1. app.getInitialProps
- // 2. page.getInitialProps
- // 3. app.render
- // 4. page.render
-
- 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);
const jssSheets = new JSSServerStyleSheets();
- ctx.renderPage = () =>
- originalRenderPage({
- enhanceApp: (App: React.ComponentType & MyAppProps>) =>
- function EnhanceApp(props) {
- return jssSheets.collect();
- },
- });
-
- const initialProps = await Document.getInitialProps(ctx);
-
- // Generate style tags for the styles coming from Emotion
- // This is important. It prevents Emotion from rendering invalid HTML.
- // See https://github.com/mui/material-ui/issues/26561#issuecomment-855286153
- const emotionStyles = extractCriticalToChunks(initialProps.html);
- const emotionStyleTags = emotionStyles.styles.map((style) => (
-
- ));
-
- // Generate the css string for the styles coming from jss
- let css = jssSheets.toString();
- // It might be undefined, e.g. after an error.
- if (css && process.env.NODE_ENV === 'production') {
- const result1 = await prefixer.process(css, { from: undefined });
- css = result1.css;
- css = cleanCSS.minify(css).styles;
- }
+ const finalProps = await documentGetInitialProps(ctx, {
+ plugins: [
+ {
+ enhanceApp: (App: React.ComponentType) =>
+ function EnhanceApp(props: AppProps) {
+ return jssSheets.collect();
+ },
+ resolveProps: async (initialProps: DocumentInitialProps) => {
+ // Generate the css string for the styles coming from jss
+ let css = jssSheets.toString();
+ // It might be undefined, e.g. after an error.
+ if (css && process.env.NODE_ENV === 'production') {
+ const result1 = await prefixer.process(css, { from: undefined });
+ css = result1.css;
+ css = cleanCSS.minify(css).styles;
+ }
- return {
- ...initialProps,
- styles: [
- ...emotionStyleTags,
- ,
- ...React.Children.toArray(initialProps.styles),
+ return {
+ ...initialProps,
+ styles: [
+ ...(Array.isArray(initialProps.styles) ? initialProps.styles : [initialProps.styles]),
+ ,
+ ...React.Children.toArray(initialProps.styles),
+ ],
+ };
+ },
+ },
],
- };
+ });
+
+ return finalProps;
};
diff --git a/examples/material-ui-nextjs-ts-v4-v5-migration/src/Link.tsx b/examples/material-ui-nextjs-ts-v4-v5-migration/src/Link.tsx
index 9783ebda346c9c..007fa266d61a05 100644
--- a/examples/material-ui-nextjs-ts-v4-v5-migration/src/Link.tsx
+++ b/examples/material-ui-nextjs-ts-v4-v5-migration/src/Link.tsx
@@ -17,7 +17,17 @@ interface NextLinkComposedProps
export const NextLinkComposed = React.forwardRef(
function NextLinkComposed(props, ref) {
- const { to, linkAs, replace, scroll, shallow, prefetch, locale, ...other } = props;
+ const {
+ to,
+ linkAs,
+ replace,
+ scroll,
+ shallow,
+ prefetch,
+ legacyBehavior = true,
+ locale,
+ ...other
+ } = props;
return (
diff --git a/examples/material-ui-nextjs-ts-v4-v5-migration/src/createEmotionCache.ts b/examples/material-ui-nextjs-ts-v4-v5-migration/src/createEmotionCache.ts
deleted file mode 100644
index 4bc81ecfeaf28e..00000000000000
--- a/examples/material-ui-nextjs-ts-v4-v5-migration/src/createEmotionCache.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import createCache from '@emotion/cache';
-
-// prepend: true moves MUI styles to the top of the so they're loaded first.
-// It allows developers to easily override MUI styles with other styling solutions, like CSS modules.
-export default function createEmotionCache() {
- return createCache({ key: 'css', prepend: true });
-}
diff --git a/examples/material-ui-nextjs-ts/package.json b/examples/material-ui-nextjs-ts/package.json
index a3c7540ca982cf..429d960765034e 100644
--- a/examples/material-ui-nextjs-ts/package.json
+++ b/examples/material-ui-nextjs-ts/package.json
@@ -15,6 +15,7 @@
"@emotion/styled": "latest",
"@mui/icons-material": "latest",
"@mui/material": "latest",
+ "@mui/material-nextjs": "latest",
"next": "latest",
"react": "latest",
"react-dom": "latest"
diff --git a/examples/material-ui-nextjs-ts/src/app/layout.tsx b/examples/material-ui-nextjs-ts/src/app/layout.tsx
index 76bfa1f6e9ca85..017035c102aeae 100644
--- a/examples/material-ui-nextjs-ts/src/app/layout.tsx
+++ b/examples/material-ui-nextjs-ts/src/app/layout.tsx
@@ -1,7 +1,10 @@
import * as React from 'react';
+import { AppRouterCacheProvider } from '@mui/material-nextjs/v14-appRouter';
+import { ThemeProvider } from '@mui/material/styles';
import Link from 'next/link';
import AppBar from '@mui/material/AppBar';
import Box from '@mui/material/Box';
+import CssBaseline from '@mui/material/CssBaseline';
import Drawer from '@mui/material/Drawer';
import Toolbar from '@mui/material/Toolbar';
import Typography from '@mui/material/Typography';
@@ -18,7 +21,7 @@ import ChecklistIcon from '@mui/icons-material/Checklist';
import SettingsIcon from '@mui/icons-material/Settings';
import SupportIcon from '@mui/icons-material/Support';
import LogoutIcon from '@mui/icons-material/Logout';
-import ThemeRegistry from '@/components/ThemeRegistry/ThemeRegistry';
+import theme from '@/theme';
export const metadata = {
title: 'Next.js App Router + Material UI v5',
@@ -43,70 +46,74 @@ export default function RootLayout({ children }: { children: React.ReactNode })
return (
-
-
-
-
-
- Next.js App Router
-
-
-
-
+
+ {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
+
+
+
+
+
+ Next.js App Router
+
+
+
+
-
-
- {LINKS.map(({ text, href, icon: Icon }) => (
-
-
-
-
-
-
-
-
- ))}
-
-
-
- {PLACEHOLDER_LINKS.map(({ text, icon: Icon }) => (
-
-
-
-
-
-
-
-
- ))}
-
-
-
- {children}
-
-
+ flexShrink: 0,
+ '& .MuiDrawer-paper': {
+ width: DRAWER_WIDTH,
+ boxSizing: 'border-box',
+ top: ['48px', '56px', '64px'],
+ height: 'auto',
+ bottom: 0,
+ },
+ }}
+ variant="permanent"
+ anchor="left"
+ >
+
+
+ {LINKS.map(({ text, href, icon: Icon }) => (
+
+
+
+
+
+
+
+
+ ))}
+
+
+
+ {PLACEHOLDER_LINKS.map(({ text, icon: Icon }) => (
+
+
+
+
+
+
+
+
+ ))}
+
+
+
+ {children}
+
+
+
);
diff --git a/examples/material-ui-nextjs-ts/src/components/ThemeRegistry/EmotionCache.tsx b/examples/material-ui-nextjs-ts/src/components/ThemeRegistry/EmotionCache.tsx
deleted file mode 100644
index aca708502f2bcc..00000000000000
--- a/examples/material-ui-nextjs-ts/src/components/ThemeRegistry/EmotionCache.tsx
+++ /dev/null
@@ -1,94 +0,0 @@
-'use client';
-import * as React from 'react';
-import createCache from '@emotion/cache';
-import { useServerInsertedHTML } from 'next/navigation';
-import { CacheProvider as DefaultCacheProvider } from '@emotion/react';
-import type { EmotionCache, Options as OptionsOfCreateCache } from '@emotion/cache';
-
-export type NextAppDirEmotionCacheProviderProps = {
- /** This is the options passed to createCache() from 'import createCache from "@emotion/cache"' */
- options: Omit;
- /** By default from 'import { CacheProvider } from "@emotion/react"' */
- CacheProvider?: (props: {
- value: EmotionCache;
- children: React.ReactNode;
- }) => React.JSX.Element | null;
- children: React.ReactNode;
-};
-
-// Adapted from https://github.com/garronej/tss-react/blob/main/src/next/appDir.tsx
-export default function NextAppDirEmotionCacheProvider(props: NextAppDirEmotionCacheProviderProps) {
- const { options, CacheProvider = DefaultCacheProvider, children } = props;
-
- const [registry] = React.useState(() => {
- const cache = createCache(options);
- cache.compat = true;
- const prevInsert = cache.insert;
- let inserted: { name: string; isGlobal: boolean }[] = [];
- cache.insert = (...args) => {
- const [selector, serialized] = args;
- if (cache.inserted[serialized.name] === undefined) {
- inserted.push({
- name: serialized.name,
- isGlobal: !selector,
- });
- }
- return prevInsert(...args);
- };
- const flush = () => {
- const prevInserted = inserted;
- inserted = [];
- return prevInserted;
- };
- return { cache, flush };
- });
-
- useServerInsertedHTML(() => {
- const inserted = registry.flush();
- if (inserted.length === 0) {
- return null;
- }
- let styles = '';
- let dataEmotionAttribute = registry.cache.key;
-
- const globals: {
- name: string;
- style: string;
- }[] = [];
-
- inserted.forEach(({ name, isGlobal }) => {
- const style = registry.cache.inserted[name];
-
- if (typeof style !== 'boolean') {
- if (isGlobal) {
- globals.push({ name, style });
- } else {
- styles += style;
- dataEmotionAttribute += ` ${name}`;
- }
- }
- });
-
- return (
-
- {globals.map(({ name, style }) => (
-
- ))}
- {styles && (
-
- )}
-
- );
- });
-
- return {children};
-}
diff --git a/examples/material-ui-nextjs-ts/src/components/ThemeRegistry/ThemeRegistry.tsx b/examples/material-ui-nextjs-ts/src/components/ThemeRegistry/ThemeRegistry.tsx
deleted file mode 100644
index 6418593aca7c9b..00000000000000
--- a/examples/material-ui-nextjs-ts/src/components/ThemeRegistry/ThemeRegistry.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-'use client';
-import * as React from 'react';
-import { ThemeProvider } from '@mui/material/styles';
-import CssBaseline from '@mui/material/CssBaseline';
-import NextAppDirEmotionCacheProvider from './EmotionCache';
-import theme from './theme';
-
-export default function ThemeRegistry({ children }: { children: React.ReactNode }) {
- return (
-
-
- {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
-
- {children}
-
-
- );
-}
diff --git a/examples/material-ui-nextjs-ts/src/components/ThemeRegistry/theme.ts b/examples/material-ui-nextjs-ts/src/theme.ts
similarity index 97%
rename from examples/material-ui-nextjs-ts/src/components/ThemeRegistry/theme.ts
rename to examples/material-ui-nextjs-ts/src/theme.ts
index f9fdd2a3142928..b105b58c5b2737 100644
--- a/examples/material-ui-nextjs-ts/src/components/ThemeRegistry/theme.ts
+++ b/examples/material-ui-nextjs-ts/src/theme.ts
@@ -1,3 +1,4 @@
+'use client';
import { Roboto } from 'next/font/google';
import { createTheme } from '@mui/material/styles';
diff --git a/examples/material-ui-nextjs/package.json b/examples/material-ui-nextjs/package.json
index 1f856819542ca7..af1228ce229f01 100644
--- a/examples/material-ui-nextjs/package.json
+++ b/examples/material-ui-nextjs/package.json
@@ -14,6 +14,7 @@
"@emotion/styled": "latest",
"@mui/icons-material": "latest",
"@mui/material": "latest",
+ "@mui/material-nextjs": "latest",
"eslint": "latest",
"eslint-config-next": "latest",
"next": "latest",
diff --git a/examples/material-ui-nextjs/src/app/layout.js b/examples/material-ui-nextjs/src/app/layout.js
index 93923885d83cd3..ac1afaad73c30c 100644
--- a/examples/material-ui-nextjs/src/app/layout.js
+++ b/examples/material-ui-nextjs/src/app/layout.js
@@ -1,7 +1,10 @@
import * as React from 'react';
import Link from 'next/link';
+import { AppRouterCacheProvider } from '@mui/material-nextjs/v14-appRouter';
+import { ThemeProvider } from '@mui/material/styles';
import AppBar from '@mui/material/AppBar';
import Box from '@mui/material/Box';
+import CssBaseline from '@mui/material/CssBaseline';
import Drawer from '@mui/material/Drawer';
import Toolbar from '@mui/material/Toolbar';
import Typography from '@mui/material/Typography';
@@ -18,7 +21,7 @@ import ChecklistIcon from '@mui/icons-material/Checklist';
import SettingsIcon from '@mui/icons-material/Settings';
import SupportIcon from '@mui/icons-material/Support';
import LogoutIcon from '@mui/icons-material/Logout';
-import ThemeRegistry from '@/components/ThemeRegistry/ThemeRegistry';
+import theme from '@/theme';
export const metadata = {
title: 'Next.js App Router + Material UI v5',
@@ -43,70 +46,74 @@ export default function RootLayout({ children }) {
return (
-
-
-
-
-
- Next.js App Router
-
-
-
-
+
+ {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
+
+
+
+
+
+ Next.js App Router
+
+
+
+
-
-
- {LINKS.map(({ text, href, icon: Icon }) => (
-
-
-
-
-
-
-
-
- ))}
-
-
-
- {PLACEHOLDER_LINKS.map(({ text, icon: Icon }) => (
-
-
-
-
-
-
-
-
- ))}
-
-
-
- {children}
-
-
+ flexShrink: 0,
+ '& .MuiDrawer-paper': {
+ width: DRAWER_WIDTH,
+ boxSizing: 'border-box',
+ top: ['48px', '56px', '64px'],
+ height: 'auto',
+ bottom: 0,
+ },
+ }}
+ variant="permanent"
+ anchor="left"
+ >
+
+
+ {LINKS.map(({ text, href, icon: Icon }) => (
+
+
+
+
+
+
+
+
+ ))}
+
+
+
+ {PLACEHOLDER_LINKS.map(({ text, icon: Icon }) => (
+
+
+
+
+
+
+
+
+ ))}
+
+
+
+ {children}
+
+
+
);
diff --git a/examples/material-ui-nextjs/src/components/ThemeRegistry/EmotionCache.js b/examples/material-ui-nextjs/src/components/ThemeRegistry/EmotionCache.js
deleted file mode 100644
index d0b6345563106c..00000000000000
--- a/examples/material-ui-nextjs/src/components/ThemeRegistry/EmotionCache.js
+++ /dev/null
@@ -1,79 +0,0 @@
-'use client';
-import * as React from 'react';
-import createCache from '@emotion/cache';
-import { useServerInsertedHTML } from 'next/navigation';
-import { CacheProvider as DefaultCacheProvider } from '@emotion/react';
-
-// Adapted from https://github.com/garronej/tss-react/blob/main/src/next/appDir.tsx
-export default function NextAppDirEmotionCacheProvider(props) {
- const { options, CacheProvider = DefaultCacheProvider, children } = props;
-
- const [registry] = React.useState(() => {
- const cache = createCache(options);
- cache.compat = true;
- const prevInsert = cache.insert;
- let inserted = [];
- cache.insert = (...args) => {
- const [selector, serialized] = args;
- if (cache.inserted[serialized.name] === undefined) {
- inserted.push({
- name: serialized.name,
- isGlobal: !selector,
- });
- }
- return prevInsert(...args);
- };
- const flush = () => {
- const prevInserted = inserted;
- inserted = [];
- return prevInserted;
- };
- return { cache, flush };
- });
-
- useServerInsertedHTML(() => {
- const inserted = registry.flush();
- if (inserted.length === 0) {
- return null;
- }
- let styles = '';
- let dataEmotionAttribute = registry.cache.key;
-
- const globals = [];
-
- inserted.forEach(({ name, isGlobal }) => {
- const style = registry.cache.inserted[name];
-
- if (typeof style !== 'boolean') {
- if (isGlobal) {
- globals.push({ name, style });
- } else {
- styles += style;
- dataEmotionAttribute += ` ${name}`;
- }
- }
- });
-
- return (
-
- {globals.map(({ name, style }) => (
-
- ))}
- {styles && (
-
- )}
-
- );
- });
-
- return {children};
-}
diff --git a/examples/material-ui-nextjs/src/components/ThemeRegistry/ThemeRegistry.js b/examples/material-ui-nextjs/src/components/ThemeRegistry/ThemeRegistry.js
deleted file mode 100644
index 421e3516b78108..00000000000000
--- a/examples/material-ui-nextjs/src/components/ThemeRegistry/ThemeRegistry.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use client';
-import * as React from 'react';
-import { ThemeProvider } from '@mui/material/styles';
-import CssBaseline from '@mui/material/CssBaseline';
-import NextAppDirEmotionCacheProvider from './EmotionCache';
-import theme from './theme';
-
-export default function ThemeRegistry({ children }) {
- return (
-
-
- {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
-
- {children}
-
-
- );
-}
diff --git a/examples/material-ui-nextjs/src/components/ThemeRegistry/theme.js b/examples/material-ui-nextjs/src/theme.js
similarity index 97%
rename from examples/material-ui-nextjs/src/components/ThemeRegistry/theme.js
rename to examples/material-ui-nextjs/src/theme.js
index f9fdd2a3142928..b105b58c5b2737 100644
--- a/examples/material-ui-nextjs/src/components/ThemeRegistry/theme.js
+++ b/examples/material-ui-nextjs/src/theme.js
@@ -1,3 +1,4 @@
+'use client';
import { Roboto } from 'next/font/google';
import { createTheme } from '@mui/material/styles';