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 thelegacyBehavior
prop 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-link
in 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.