diff --git a/docs/data/material/getting-started/example-projects/example-projects.md b/docs/data/material/getting-started/example-projects/example-projects.md
index 9a3d39826c4f7f..f819dc2fa1f546 100644
--- a/docs/data/material/getting-started/example-projects/example-projects.md
+++ b/docs/data/material/getting-started/example-projects/example-projects.md
@@ -18,6 +18,7 @@ You can find some example projects in the [GitHub repository](https://github.com
- [Tailwind CSS](https://github.com/mui/material-ui/tree/master/examples/tailwind-css)
- [Vite.js](https://github.com/mui/material-ui/tree/master/examples/vitejs)
- [Use styled-components as style engine](https://github.com/mui/material-ui/tree/master/examples/create-react-app-with-styled-components) ([TypeScript version](https://github.com/mui/material-ui/tree/master/examples/create-react-app-with-styled-components-typescript))
+- [Next.js + @mui/styles (v4 migration helper)](https://github.com/mui/material-ui/tree/master/examples/nextjs-with-typescript-v4-migration)
Create React App is an awesome project for learning React.
Have a look at [the alternatives available](https://github.com/facebook/create-react-app/blob/HEAD/README.md#popular-alternatives) to see which project best fits your needs.
diff --git a/docs/data/material/migration/migration-v4/migrating-from-jss.md b/docs/data/material/migration/migration-v4/migrating-from-jss.md
index 7d19b7a3b65a45..96ee4b3ea01c41 100644
--- a/docs/data/material/migration/migration-v4/migrating-from-jss.md
+++ b/docs/data/material/migration/migration-v4/migrating-from-jss.md
@@ -17,6 +17,10 @@ One of the biggest changes in v5 is the replacement of JSS for [Emotion](https:/
Note that you may continue to use JSS for adding overrides for the components (e.g. `makeStyles`, `withStyles`) even after migrating to v5.
Then, if at any point you want to move over to the new styling engine, you can refactor your components progressively.
+:::info
+If you are using Next.js and you are not sure how to configure SSR to work with both Emotion & JSS, take a look a this [example project](https://github.com/mui/material-ui/tree/master/examples/nextjs-with-typescript-v4-migration).
+:::
+
This document reviews all the steps necessary to migrate away from JSS.
While you can use either of the following two options, the first is considered preferable:
diff --git a/docs/data/material/migration/migration-v4/migration-v4.md b/docs/data/material/migration/migration-v4/migration-v4.md
index 0fa26d74295b6c..92aea69c39ee5e 100644
--- a/docs/data/material/migration/migration-v4/migration-v4.md
+++ b/docs/data/material/migration/migration-v4/migration-v4.md
@@ -27,6 +27,10 @@ This process is covered in [Migrating from JSS](/material-ui/migration/migrating
Need to refer back to an older version of the docs? Check out [the v4 documentation here](https://v4.mui.com/).
:::
+:::info
+If you are using Next.js and you are not sure how to configure SSR to work with both Emotion & JSS, take a look a this [example project](https://github.com/mui/material-ui/tree/master/examples/nextjs-with-typescript-v4-migration).
+:::
+
## Why you should migrate
Material UI v5 includes many bug fixes and improvements over v4.
diff --git a/examples/nextjs-with-typescript-v4-migration/.gitignore b/examples/nextjs-with-typescript-v4-migration/.gitignore
new file mode 100644
index 00000000000000..0a5247fbb5ad45
--- /dev/null
+++ b/examples/nextjs-with-typescript-v4-migration/.gitignore
@@ -0,0 +1,37 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# local env files
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
\ No newline at end of file
diff --git a/examples/nextjs-with-typescript-v4-migration/README.md b/examples/nextjs-with-typescript-v4-migration/README.md
new file mode 100644
index 00000000000000..f453b64decf861
--- /dev/null
+++ b/examples/nextjs-with-typescript-v4-migration/README.md
@@ -0,0 +1,42 @@
+# Material UI v5 and Next.js example with @mui/styles (in TypeScript)
+
+## How to use
+
+Download the example [or clone the repo](https://github.com/mui/material-ui):
+
+
+
+```sh
+curl https://codeload.github.com/mui/material-ui/tar.gz/master | tar -xz --strip=2 material-ui-master/examples/nextjs-with-typescript
+cd nextjs-with-typescript
+```
+
+Install it and run:
+
+```sh
+npm install
+npm run dev
+```
+
+or:
+
+
+
+[![Edit on StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/mui/material-ui/tree/master/examples/nextjs-with-typescript-v4-migration)
+
+[![Edit on CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/mui/material-ui/tree/master/examples/nextjs-with-typescript-v4-migration)
+
+## The idea behind the example
+
+The project uses [Next.js](https://github.com/vercel/next.js), which is a framework for server-rendered React apps.
+It includes `@mui/material` and its peer dependencies, including `emotion`, the default style engine in Material UI v5. If you prefer, you can [use styled-components instead](https://mui.com/material-ui/guides/interoperability/#styled-components).
+It also includes `@mui/styles`, the legacy styling solution that uses JSS as an engine.
+It provides all the necessary config for working with both Emotion and JSS for server-side rendering.
+The project is intended as a basic starter for migrating your application from v4 to v5, as it lets the JSS style overrides take precedence over the default styles passed to the components by Emotion.
+It demonstrates what results after handling v5's breaking changes to the [theme](https://mui.com/material-ui/migration/v5-style-changes/) and [components](https://mui.com/material-ui/migration/v5-component-changes/).
+
+## The Link component
+
+Next.js has [a custom Link component](https://nextjs.org/docs/api-reference/next/link).
+The example folder provides adapters for usage with Material UI.
+You can find more information [in the documentation](https://mui.com/material-ui/guides/routing/#next-js).
diff --git a/examples/nextjs-with-typescript-v4-migration/next-env.d.ts b/examples/nextjs-with-typescript-v4-migration/next-env.d.ts
new file mode 100644
index 00000000000000..4f11a03dc6cc37
--- /dev/null
+++ b/examples/nextjs-with-typescript-v4-migration/next-env.d.ts
@@ -0,0 +1,5 @@
+///
+///
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/examples/nextjs-with-typescript-v4-migration/next.config.js b/examples/nextjs-with-typescript-v4-migration/next.config.js
new file mode 100644
index 00000000000000..3dd7ef15191a9f
--- /dev/null
+++ b/examples/nextjs-with-typescript-v4-migration/next.config.js
@@ -0,0 +1,4 @@
+/** @type {import('next').NextConfig} */
+module.exports = {
+ reactStrictMode: true,
+};
diff --git a/examples/nextjs-with-typescript-v4-migration/package.json b/examples/nextjs-with-typescript-v4-migration/package.json
new file mode 100644
index 00000000000000..cd2f52c75d43bc
--- /dev/null
+++ b/examples/nextjs-with-typescript-v4-migration/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "nextjs-with-typescript-with-mui-styles",
+ "version": "5.0.0",
+ "private": true,
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start",
+ "lint": "next lint",
+ "post-update": "echo \"codesandbox preview only, need an update\" && yarn upgrade --latest"
+ },
+ "dependencies": {
+ "@emotion/cache": "^11.7.1",
+ "@emotion/react": "^11.9.0",
+ "@emotion/server": "^11.4.0",
+ "@emotion/styled": "^11.8.1",
+ "@mui/icons-material": "latest",
+ "@mui/material": "latest",
+ "@mui/styles": "latest",
+ "next": "12.1.5",
+ "react": "^17.0.2",
+ "react-dom": "^17.0.2"
+ },
+ "devDependencies": {
+ "@types/node": "latest",
+ "@types/react": "17.0.2",
+ "eslint": "latest",
+ "eslint-config-next": "latest",
+ "typescript": "latest"
+ }
+}
diff --git a/examples/nextjs-with-typescript-v4-migration/pages/_app.tsx b/examples/nextjs-with-typescript-v4-migration/pages/_app.tsx
new file mode 100644
index 00000000000000..f71405f34ad4ed
--- /dev/null
+++ b/examples/nextjs-with-typescript-v4-migration/pages/_app.tsx
@@ -0,0 +1,40 @@
+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 '../src/theme';
+import createEmotionCache from '../src/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;
+
+ React.useEffect(() => {
+ // Remove the server-side injected CSS.
+ const jssStyles = document.querySelector('#jss-server-side');
+ if (jssStyles) {
+ jssStyles?.parentElement?.removeChild(jssStyles);
+ }
+ }, []);
+
+ return (
+
+
+
+
+
+ {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
+
+
+
+
+ );
+}
diff --git a/examples/nextjs-with-typescript-v4-migration/pages/_document.tsx b/examples/nextjs-with-typescript-v4-migration/pages/_document.tsx
new file mode 100644
index 00000000000000..eff5c47e478538
--- /dev/null
+++ b/examples/nextjs-with-typescript-v4-migration/pages/_document.tsx
@@ -0,0 +1,130 @@
+import * as React from 'react';
+import Document, { Html, Head, Main, NextScript } from 'next/document';
+import createEmotionServer from '@emotion/server/create-instance';
+import { ServerStyleSheets as JSSServerStyleSheets } from '@mui/styles';
+import theme from '../src/theme';
+import createEmotionCache from '../src/createEmotionCache';
+
+export default class MyDocument extends Document {
+ render() {
+ return (
+
+
+ {/* PWA primary color */}
+
+
+
+ {/* Inject MUI styles first to match with the prepend: true configuration. */}
+ {(this.props as any).emotionStyleTags}
+
+
+
+
+
+
+ );
+ }
+}
+
+// You can find a benchmark of the available CSS minifiers under
+// https://github.com/GoalSmashers/css-minification-benchmark
+// We have found that clean-css is faster than cssnano but the output is larger.
+// Waiting for https://github.com/cssinjs/jss/issues/279
+// 4% slower but 12% smaller output than doing it in a single step.
+//
+// It's using .browserslistrc
+let prefixer: any;
+let cleanCSS: any;
+if (process.env.NODE_ENV === 'production') {
+ /* eslint-disable global-require */
+ const postcss = require('postcss');
+ const autoprefixer = require('autoprefixer');
+ const CleanCSS = require('clean-css');
+ /* eslint-enable global-require */
+
+ prefixer = postcss([autoprefixer]);
+ cleanCSS = new CleanCSS();
+}
+
+// `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);
+ const jssSheets = new JSSServerStyleSheets();
+
+ ctx.renderPage = () =>
+ originalRenderPage({
+ enhanceApp: (App: any) =>
+ 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) => (
+
+ ));
+
+ // Gemerate 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),
+ ],
+ };
+};
diff --git a/examples/nextjs-with-typescript-v4-migration/pages/about.tsx b/examples/nextjs-with-typescript-v4-migration/pages/about.tsx
new file mode 100644
index 00000000000000..bdd45d7720b6da
--- /dev/null
+++ b/examples/nextjs-with-typescript-v4-migration/pages/about.tsx
@@ -0,0 +1,43 @@
+import * as React from 'react';
+import type { NextPage } from 'next';
+import Container from '@mui/material/Container';
+import Typography from '@mui/material/Typography';
+import Box from '@mui/material/Box';
+import Button from '@mui/material/Button';
+import { makeStyles } from '@mui/styles';
+import Link from '../src/Link';
+import ProTip from '../src/ProTip';
+import Copyright from '../src/Copyright';
+
+const useStyles = makeStyles((theme) => ({
+ main: {
+ marginTop: theme.spacing(4),
+ marginBottom: theme.spacing(4),
+ display: 'flex',
+ flexDirection: 'column',
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+}));
+
+const About: NextPage = () => {
+ const classes = useStyles();
+ return (
+
+
+
+ MUI v5 + Next.js with TypeScript example
+
+
+
+
+
+
+
+
+ );
+};
+
+export default About;
diff --git a/examples/nextjs-with-typescript-v4-migration/pages/index.tsx b/examples/nextjs-with-typescript-v4-migration/pages/index.tsx
new file mode 100644
index 00000000000000..cbf5d540c9ce97
--- /dev/null
+++ b/examples/nextjs-with-typescript-v4-migration/pages/index.tsx
@@ -0,0 +1,40 @@
+import * as React from 'react';
+import type { NextPage } from 'next';
+import Container from '@mui/material/Container';
+import Typography from '@mui/material/Typography';
+import { makeStyles } from '@mui/styles';
+import Link from '../src/Link';
+import ProTip from '../src/ProTip';
+import Copyright from '../src/Copyright';
+
+const useStyles = makeStyles((theme) => ({
+ main: {
+ marginTop: theme.spacing(4),
+ marginBottom: theme.spacing(4),
+ display: 'flex',
+ flexDirection: 'column',
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+}));
+
+const Home: NextPage = () => {
+ const classes = useStyles();
+
+ return (
+
+
+
+ MUI v5 + Next.js with TypeScript example
+
+
+ Go to the about page
+
+
+
+