Noh | エンジニア向け情報共有コミュニティ
Signup / Login

Next.js 13でMUIのLinkを使う

mui
nextjs
react
javascript
typescript

投稿日: 2024/06/25

更新日: 2024/07/30

MUI (旧 material-ui )の実用小ネタ集

Next.jsとMUIを用いてるときにリンクする方法について調べると以下のコードを見かけます。

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> ) }

しかし、このコードはNext.js13においてエラーになります。

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.

これはNext.js13のLinkの仕様変更でaタグのラッパーをレンダリングするように変わったからみたいです。
https://github.com/vercel/next.js/discussions/49508

したがって以下のようなHTMLをレンダリングしており、NextのLinkとMUIのLinkがそれぞれaタグを出力してます。

<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タグの中にaタグが入ってることで警告が出てます。

解決方法

最終的に以下のように書くことで回避できました。
MUIのLinkコンポーネントの引数にNextjsのLinkコンポーネントを渡します。

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> ) }

レンダリングされるHTMLは以下のような感じです。

<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>
yosi

Noh を作ってるエンジニア。

目次