diff --git a/babel.config.js b/babel.config.js
index eca2870ce49edb..754eaac1536070 100644
--- a/babel.config.js
+++ b/babel.config.js
@@ -31,6 +31,7 @@ module.exports = function getBabelConfig(api) {
'@mui/base': resolveAliasPath('./packages/mui-base/src'),
'@mui/utils': resolveAliasPath('./packages/mui-utils/src'),
'@mui/material-next': resolveAliasPath('./packages/mui-material-next/src'),
+ '@mui/material-nextjs': resolveAliasPath('./packages/mui-material-nextjs/src'),
'@mui/joy': resolveAliasPath('./packages/mui-joy/src'),
'@mui/zero-runtime': resolveAliasPath('./packages/zero-runtime/src'),
docs: resolveAliasPath('./docs'),
diff --git a/docs/data/material/guides/nextjs/nextjs.md b/docs/data/material/guides/nextjs/nextjs.md
index 08ff785fc1b687..2d724034821d0a 100644
--- a/docs/data/material/guides/nextjs/nextjs.md
+++ b/docs/data/material/guides/nextjs/nextjs.md
@@ -59,6 +59,35 @@ This option ensures that the styles generated by Material UI will be wrapped in
To learn more about it, see [the MDN CSS layer documentation](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer).
+### Link
+
+The package provides a thin wrapper Link component that combines the functionality of the Next.js [Link](https://nextjs.org/docs/api-reference/next/link) and the styles of Material UI [Link](https://mui.com/components/links/).
+
+You can pass any props supported by both components to the Link.
+
+```js
+import { Link } from '@mui/material-nextjs/v13-appRouter'; // or `v14-appRouter` if you are using Next.js v14
+
+function Nav() {
+ return (
+
+
+ Dashboard
+
+
+ );
+}
+```
+
+To learn more about the supported props, visit:
+
+- Next.js related props: [Next.js Link](https://nextjs.org/docs/app/api-reference/components/link#props)
+- Material UI related props: [Material UI Link](/material-ui/react-link/)
+
+:::warning
+Do not use the Link from `@mui/material-nextjs/*-pagesRouter` for App Router.
+:::
+
## Pages Router
This section walks through the Material UI integration with the Next.js [Pages Router](https://nextjs.org/docs/pages/building-your-application), for both [Server Side Rendering](https://nextjs.org/docs/pages/building-your-application/rendering/server-side-rendering) (SSR) and [Static Site Generation](https://nextjs.org/docs/pages/building-your-application/rendering/static-site-generation) (SSG).
@@ -149,3 +178,30 @@ If you are using TypeScript, add `DocumentHeadTagsProps` to the Document's props
...
}
```
+
+### Link
+
+For pages router, use the Link only from `@mui/material-nextjs/*-pagesRouter`:
+
+```js
+import { Link } from '@mui/material-nextjs/v13-pagesRouter'; // or `v14-pagesRouter` if you are using Next.js v14
+
+function Nav() {
+ return (
+
+
+ Dashboard
+
+
+ );
+}
+```
+
+To learn more about the supported props, visit:
+
+- Next.js related props: [Next.js Link](https://nextjs.org/docs/pages/api-reference/components/link#props)
+- Material UI related props: [Material UI Link](/material-ui/react-link/)
+
+:::warning
+Do not use the Link from `@mui/material-nextjs/*-appRouter` for Pages Router.
+:::
diff --git a/packages/mui-material-nextjs/package.json b/packages/mui-material-nextjs/package.json
index 1daef8f6a664b6..75b17a20f12763 100644
--- a/packages/mui-material-nextjs/package.json
+++ b/packages/mui-material-nextjs/package.json
@@ -36,6 +36,9 @@
"test": "cd ../../ && cross-env NODE_ENV=test mocha 'packages/mui-utils/**/*.test.{js,ts,tsx}'",
"typescript": "tsc -p tsconfig.json"
},
+ "dependencies": {
+ "clsx": "^2.1.0"
+ },
"devDependencies": {
"@emotion/cache": "^11.11.0",
"@emotion/react": "^11.5.0",
diff --git a/packages/mui-material-nextjs/src/v13-appRouter/Link/Link.spec.tsx b/packages/mui-material-nextjs/src/v13-appRouter/Link/Link.spec.tsx
new file mode 100644
index 00000000000000..7d581136f7df5f
--- /dev/null
+++ b/packages/mui-material-nextjs/src/v13-appRouter/Link/Link.spec.tsx
@@ -0,0 +1,25 @@
+import * as React from 'react';
+import { Link } from '@mui/material-nextjs/v13-appRouter';
+
+// @ts-expect-error href is required by Next.js
+;
+;
+;
+
+ Dashboard
+;
+
+ Dashboard
+;
+
+ Dashboard
+;
+
+;
+;
+;
diff --git a/packages/mui-material-nextjs/src/v13-appRouter/Link/Link.tsx b/packages/mui-material-nextjs/src/v13-appRouter/Link/Link.tsx
new file mode 100644
index 00000000000000..9155fcffedfd53
--- /dev/null
+++ b/packages/mui-material-nextjs/src/v13-appRouter/Link/Link.tsx
@@ -0,0 +1,63 @@
+'use client';
+import * as React from 'react';
+import clsx from 'clsx';
+import { usePathname } from 'next/navigation';
+import NextLink, { LinkProps as NextLinkProps } from 'next/link';
+import MuiLink, { LinkOwnProps as MuiLinkProps } from '@mui/material/Link';
+import linkClasses from './linkClasses';
+
+export interface LinkProps
+ extends Omit,
+ MuiLinkProps {
+ /**
+ * Extra class name to apply to the link.
+ */
+ className?: string;
+ /**
+ * The active class name to apply when the current page is the same as the link's href.
+ * @default 'Mui-active'
+ */
+ activeClassName?: string;
+}
+
+const Link = React.forwardRef(function Link(
+ {
+ href,
+ replace,
+ scroll,
+ shallow,
+ prefetch,
+ locale,
+ as,
+ className: classNameProp,
+ activeClassName = linkClasses.active,
+ ...muiLinkProps
+ },
+ ref,
+) {
+ const nextPathname = usePathname();
+ const pathname = typeof href === 'string' ? href : href.pathname;
+ const className = clsx(classNameProp, {
+ [activeClassName]: nextPathname === pathname && activeClassName,
+ });
+ return (
+
+
+
+ );
+});
+
+export default Link;
diff --git a/packages/mui-material-nextjs/src/v13-appRouter/Link/index.ts b/packages/mui-material-nextjs/src/v13-appRouter/Link/index.ts
new file mode 100644
index 00000000000000..b0958cdbcfbb49
--- /dev/null
+++ b/packages/mui-material-nextjs/src/v13-appRouter/Link/index.ts
@@ -0,0 +1,4 @@
+export { default as Link } from './Link';
+export { default as linkClasses, getLinkUtilityClass } from './linkClasses';
+export type { LinkProps } from './Link';
+export type { LinkClasses } from './linkClasses';
diff --git a/packages/mui-material-nextjs/src/v13-appRouter/Link/linkClasses.ts b/packages/mui-material-nextjs/src/v13-appRouter/Link/linkClasses.ts
new file mode 100644
index 00000000000000..6c2438e043732a
--- /dev/null
+++ b/packages/mui-material-nextjs/src/v13-appRouter/Link/linkClasses.ts
@@ -0,0 +1,26 @@
+import generateUtilityClasses from '@mui/utils/generateUtilityClasses';
+import generateUtilityClass from '@mui/utils/generateUtilityClass';
+import { LinkClasses as MuiLinkClasses } from '@mui/material/Link';
+
+export interface LinkClasses extends MuiLinkClasses {
+ /**
+ * Styles applied to the root element when the link is active.
+ */
+ active: string;
+}
+
+export function getLinkUtilityClass(slot: string): string {
+ return generateUtilityClass('MuiLink', slot);
+}
+
+const linkClasses: LinkClasses = generateUtilityClasses('MuiLink', [
+ 'root',
+ 'underlineNone',
+ 'underlineHover',
+ 'underlineAlways',
+ 'button',
+ 'focusVisible',
+ 'active',
+]);
+
+export default linkClasses;
diff --git a/packages/mui-material-nextjs/src/v13-appRouter/index.ts b/packages/mui-material-nextjs/src/v13-appRouter/index.ts
index 3b153dde004ec4..80eb6c9856903a 100644
--- a/packages/mui-material-nextjs/src/v13-appRouter/index.ts
+++ b/packages/mui-material-nextjs/src/v13-appRouter/index.ts
@@ -1,3 +1,4 @@
'use client';
export { default as AppRouterCacheProvider } from './appRouterV13';
export * from './appRouterV13';
+export * from './Link';
diff --git a/packages/mui-material-nextjs/src/v13-pagesRouter/Link/Link.spec.tsx b/packages/mui-material-nextjs/src/v13-pagesRouter/Link/Link.spec.tsx
new file mode 100644
index 00000000000000..da130376674539
--- /dev/null
+++ b/packages/mui-material-nextjs/src/v13-pagesRouter/Link/Link.spec.tsx
@@ -0,0 +1,25 @@
+import * as React from 'react';
+import { Link } from '@mui/material-nextjs/v13-pagesRouter';
+
+// @ts-expect-error href is required by Next.js
+;
+;
+;
+
+ Dashboard
+;
+
+ Dashboard
+;
+
+ Dashboard
+;
+
+;
+;
+;
diff --git a/packages/mui-material-nextjs/src/v13-pagesRouter/Link/Link.tsx b/packages/mui-material-nextjs/src/v13-pagesRouter/Link/Link.tsx
new file mode 100644
index 00000000000000..c6e947b810cf0a
--- /dev/null
+++ b/packages/mui-material-nextjs/src/v13-pagesRouter/Link/Link.tsx
@@ -0,0 +1,63 @@
+'use client';
+import * as React from 'react';
+import clsx from 'clsx';
+import { useRouter } from 'next/router';
+import NextLink, { LinkProps as NextLinkProps } from 'next/link';
+import MuiLink, { LinkOwnProps as MuiLinkProps } from '@mui/material/Link';
+import linkClasses from './linkClasses';
+
+export interface LinkProps
+ extends Omit,
+ MuiLinkProps {
+ /**
+ * Extra class name to apply to the link.
+ */
+ className?: string;
+ /**
+ * The active class name to apply when the current page is the same as the link's href.
+ * @default 'Mui-active'
+ */
+ activeClassName?: string;
+}
+
+const Link = React.forwardRef(function Link(
+ {
+ href,
+ replace,
+ scroll,
+ shallow,
+ prefetch,
+ locale,
+ as,
+ className: classNameProp,
+ activeClassName = linkClasses.active,
+ ...muiLinkProps
+ },
+ ref,
+) {
+ const router = useRouter();
+ const pathname = typeof href === 'string' ? href : href.pathname;
+ const className = clsx(classNameProp, {
+ [activeClassName]: router.pathname === pathname && activeClassName,
+ });
+ return (
+
+
+
+ );
+});
+
+export default Link;
diff --git a/packages/mui-material-nextjs/src/v13-pagesRouter/Link/index.ts b/packages/mui-material-nextjs/src/v13-pagesRouter/Link/index.ts
new file mode 100644
index 00000000000000..b0958cdbcfbb49
--- /dev/null
+++ b/packages/mui-material-nextjs/src/v13-pagesRouter/Link/index.ts
@@ -0,0 +1,4 @@
+export { default as Link } from './Link';
+export { default as linkClasses, getLinkUtilityClass } from './linkClasses';
+export type { LinkProps } from './Link';
+export type { LinkClasses } from './linkClasses';
diff --git a/packages/mui-material-nextjs/src/v13-pagesRouter/Link/linkClasses.ts b/packages/mui-material-nextjs/src/v13-pagesRouter/Link/linkClasses.ts
new file mode 100644
index 00000000000000..6c2438e043732a
--- /dev/null
+++ b/packages/mui-material-nextjs/src/v13-pagesRouter/Link/linkClasses.ts
@@ -0,0 +1,26 @@
+import generateUtilityClasses from '@mui/utils/generateUtilityClasses';
+import generateUtilityClass from '@mui/utils/generateUtilityClass';
+import { LinkClasses as MuiLinkClasses } from '@mui/material/Link';
+
+export interface LinkClasses extends MuiLinkClasses {
+ /**
+ * Styles applied to the root element when the link is active.
+ */
+ active: string;
+}
+
+export function getLinkUtilityClass(slot: string): string {
+ return generateUtilityClass('MuiLink', slot);
+}
+
+const linkClasses: LinkClasses = generateUtilityClasses('MuiLink', [
+ 'root',
+ 'underlineNone',
+ 'underlineHover',
+ 'underlineAlways',
+ 'button',
+ 'focusVisible',
+ 'active',
+]);
+
+export default linkClasses;
diff --git a/packages/mui-material-nextjs/src/v13-pagesRouter/index.ts b/packages/mui-material-nextjs/src/v13-pagesRouter/index.ts
index ff4f92e5707270..b8fa76c3417865 100644
--- a/packages/mui-material-nextjs/src/v13-pagesRouter/index.ts
+++ b/packages/mui-material-nextjs/src/v13-pagesRouter/index.ts
@@ -1,2 +1,3 @@
export * from './pagesRouterV13Document';
export * from './pagesRouterV13App';
+export * from './Link';
diff --git a/packages/mui-material-nextjs/tsconfig.build.json b/packages/mui-material-nextjs/tsconfig.build.json
index 405e223d9a9bad..e40d6e52ebaa3d 100644
--- a/packages/mui-material-nextjs/tsconfig.build.json
+++ b/packages/mui-material-nextjs/tsconfig.build.json
@@ -11,5 +11,6 @@
"rootDir": "./src"
},
"include": ["./src/**/*.ts*"],
- "exclude": ["src/**/*.spec.ts*", "src/**/*.test.ts*"]
+ "exclude": ["src/**/*.spec.ts*", "src/**/*.test.ts*"],
+ "references": [{ "path": "../mui-material/tsconfig.build.json" }]
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 899327c1ce4300..9737a65f0efd2e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1708,6 +1708,9 @@ importers:
'@mui/material':
specifier: ^5.0.0
version: link:../mui-material/build
+ clsx:
+ specifier: ^2.1.0
+ version: 2.1.0
devDependencies:
'@emotion/cache':
specifier: ^11.11.0