Linkコンポーネントで<a>要素を包むというのは、Next.jsのサンプルでよく見かけるコードです。ところが、Next.jsの最新バージョンでは、サーバーエラーが起こるようになりました。本稿は、その理由と解決方法についてご説明します。
エラーの内容
エラーで告げられるメッセージはつぎのとおりです。
Server Error
Error: Invalid<Link>with<a>child. Please remove<a>or use<Link legacyBehavior>.
解決方法も示されています。けれど、なぜエラーが生じるようになったのか、わからないことには納得いきません。
なぜエラーが起こったのか
これまで(Next.js 12.2より前)は、Linkコンポーネントは子に<a>要素を含むことが求められてきました。それが、もはや要らなくなったのです。
Note: Before Next.js 12.2, it was required that the Link component wrapped an
<a>tag, but this is not required in versions 12.2 and above(「Navigate Between Pages」).
むしろ、冒頭で見たとおり、<a>タグを子要素に含むとエラーになってしまいます。Linkコンポーネントが<a>要素に置き替えられるため、入れ子になるからです。
どう対応すればよいか
エラーの解消には、3つのやり方があります。
<a>要素を除く
第1は、エラーメッセージのとおり、<a>タグを外すことです。要らないものは除くのが、もっとも端的でしょう。「next/link」のサンプルコードも、あっさりそれを基本としています。
legacyBehaviorプロパティを加える
第2に、すでにアプリケーションがつくられている場合、<a>タグをすべて消そうとすると問題が起きるかもしれません。そのために用意されたのがlegacyBehaviorプロパティです。Linkコンポーネントに含めた<a>要素の扱いをこれまでと同じにしてくれます。
legacyBehavior- Changes behavior so that child must be<a>. Defaults to false(「If the child is<a>tag」).
import Link from 'next/link'
function Legacy() {
	return (
		<Link href="/about" legacyBehavior>
			<a>About Us</a>
		</Link>
	)
}
export default Legacy
The next/link child can no longer be
<a>. Add thelegacyBehaviorprop to use the legacy behavior or remove the<a>to upgrade. A codemod is available to automatically upgrade your code(「Breaking Changes」).
legacyBehaviorを使えば、以前のバージョンとの互換性も保てるのです。
next/link no longer requires manually adding
<a>as a child. You can now opt into this behavior in a backward-compatible way(「Other Improvements」).
codemodを使う
第3の解決方法は、公式サイトにはごくあっさりと説明されています。codemodを用いることです(「Invalid <Link> with <a> child」参照)。これまでのLinkコンポーネントの子の<a>タグも、新しいバージョンに対応させてくれます。
プロジェクトのルートで、codemodをつぎのように実行してください。
To run the codemod, run
npx @next/codemod new-linkin the root of your project(「Rework<Link>behavior (backwards compatible)」).
npx @next/codemod new-link
まとめ
「Upgrade Guide」の「v13 Summary」に対応がまとまっています。
- 
Linkコンポーネントの子の<a>タグを外す。
- 
LinkコンポーネントにlegacyBehaviorを加える。
- アプリケーションのルートでcodemodを実行する。
The next/link child can no longer be
<a>. Add the legacyBehavior prop to use the legacy behavior or remove the<a>to upgrade. A codemod is available to automatically upgrade your code.
