Using MUI Link in Next.js 13
投稿日: 2024/06/25
更新日: 2024/07/01
This article is a translation of the following article.
When researching how to link pages using Next.js and MUI, you may come across the following code.
import { FC } from "react" import NextLink from "next/link" import { Typography, Link as MuiLink } from "@mui/material" export const TopPage: FC = () => { return ( <NextLink passHref href="/"> <MuiLink underline="none"> <Typography variant="h5" component="div"> aaaa </Typography> </MuiLink> </NextLink> ) }
However, this code will produce an error in Next.js 13.
Unhandled Runtime Error Error: Hydration failed because the initial UI does not match what was rendered on the server. Warning: Expected server HTML to contain a matching <a> in <a>. See more info here: https://nextjs.org/docs/messages/react-hydration-error
Unhandled Runtime Error Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.
It seems that with the specification change of Link in Next.js 13, it now renders a wrapper around the a tag.
https://github.com/vercel/next.js/discussions/49508
Therefore, the following HTML is being rendered with Next's Link and MUI's Link each outputting an a
tag.
<a href="/"> <a class="MuiTypography-root MuiTypography-inherit MuiLink-root MuiLink-underlineNone css-bfksxn-MuiTypography-root-MuiLink-root"> <div class="MuiTypography-root MuiTypography-h5 css-ag7rrr-MuiTypography-root"> aaaa </div> </a> </a>
A warning is being displayed because there is an <a>
tag nested inside another <a>
tag.
Solution
I was able to avoid it by writing it as follows in the end.
Pass the Next.js Link component as an argument to the MUI Link component.
import { FC } from "react" import NextLink from "next/link" import { Typography, Link as MuiLink } from "@mui/material" export const TopPage: FC = () => { return ( <MuiLink component={NextLink} href="/" underline="none"> <Typography variant="h5" component="div"> aaaa </Typography> </MuiLink> ) }
The rendered HTML looks like the following:
<a class="MuiTypography-root MuiTypography-inherit MuiLink-root MuiLink-underlineNone css-bfksxn-MuiTypography-root-MuiLink-root" href="/"> <div class="MuiTypography-root MuiTypography-h5 css-ag7rrr-MuiTypography-root"> aaaa </div> </a>