Closed3

Next.js 13でMUIのLinkを使う

yosiyosi

この記事は以下のページに移動しました。

https://noh.ink/articles/7MwT1qTAssY18MA22Zr0




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.
yosiyosi

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

yosiyosi

最終的に以下のように書くことで回避できました。

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>
このスクラップは2023/10/09にクローズされました