Make Material UI Use NextJS Links Internally by Default for Flawless Navigation
Tech
NextJS has its own Link
component which is an extended HTML <a>
element. It provides client-side navigation and prefetching. MUI provides Link
component as well. Now you probably want to combine them together to get NextJS navigation benefits and the styling and theme from MUI.
Fortunately MUI offers a way to override the component MUI uses links for Link
and Button
directly in the theme. We need to create a forward ref to the NextJS Link
component to which we'll pass all the props and then use our new component in the theme.
1import { createTheme } from '@mui/material/styles';
2import NextLink from 'next/link';
3import { forwardRef, LegacyRef } from 'react';
4
5const MUINextLink = forwardRef(function MUINextLink(props: any, ref: LegacyRef<HTMLAnchorElement>) {
6 return <NextLink ref={ref} {...props} />;
7})
8
9const mainTheme = createTheme({
10 components: {
11 MuiLink: {
12 defaultProps: {
13 component: MUINextLink
14 }
15 },
16 MuiButtonBase: {
17 defaultProps: {
18 LinkComponent: MUINextLink
19 }
20 }
21 },
22 // ...
23})
The LegacyRef<HTMLAnchorElement>
type definition is required otherwise TypeScript complains - despite it being completely fine and the ref
working as it should. Older solution for NextJS 13 and earlier is to wrap the MUI Link (without href)
with NextJS Link (with href)
and then use the passHref
attribute.
1import NextLink from 'next/link'
2import { Link as MUILink } from '@mui/material';
3
4<NextLink href="/" passHref>
5 <MUILink variant="body2">Your Link</MUILink>
6</NextLink>
7