Next.jsでリンクを新しいタブで開く方法
問題点
Next.jsアプリケーションで外部リンク(Twitterなど)を新しいタブで開こうとした際、以下のようなコードを書くとESLintエラーが発生します:
<Link href="https://twitter.com/" passHref>
<a target="_blank">
<div className={`${dark ? styles.iconTwitterWhite : styles.iconTwitter} mr-3`} />
</a>
</Link>
エラーメッセージ:
ESLint: The href attribute is required for an anchor to be keyboard accessible. Provide a valid, navigable address as the href value.
解決策
方法1: 外部リンクには通常の <a>
タグを使用する(推奨)
外部サイトへのリンクの場合、Next.jsのLink
コンポーネントは不要です。単純な<a>
タグを使用しましょう:
<a
href="https://twitter.com/"
target="_blank"
rel="noopener noreferrer"
>
<div className={`${dark ? styles.iconTwitterWhite : styles.iconTwitter} mr-3`} />
</a>
TIP
rel="noopener noreferrer"
はセキュリティ上重要です:
- noopener: 新しいタブが元のページにアクセスできないようにする
- noreferrer: Refererヘッダーを送信しないようにする
方法2: Next.js 13以降でLinkコンポーネントを直接使用する
Next.js 13以降では、Link
コンポーネントが<a>
タグを内部でレンダリングするようになりました:
<Link
href="https://twitter.com/"
target="_blank"
rel="noopener noreferrer"
>
<div className={`${dark ? styles.iconTwitterWhite : styles.iconTwitter} mr-3`} />
</Link>
方法3: 従来の動作が必要な場合(Next.js 12以前)
古いバージョンのNext.jsを使用している場合や、特定の動作が必要な場合はlegacyBehavior
を使用します:
<Link href="https://twitter.com/" passHref legacyBehavior>
<a target="_blank" rel="noopener noreferrer">
<div className={`${dark ? styles.iconTwitterWhite : styles.iconTwitter} mr-3`} />
</a>
</Link>
ベストプラクティス
外部リンクと内部リンクの使い分け
- 外部リンク(他のドメイン):通常の
<a>
タグを使用 - 内部リンク(同じアプリ内):Next.jsの
Link
コンポーネントを使用
設定ファイルの活用
リンクURLを設定ファイルにまとめることをおすすめします:
// config/site.js
export const siteConfig = {
links: {
twitter: "https://twitter.com/username",
github: "https://github.com/username",
linkedin: "https://linkedin.com/in/username",
},
};
// コンポーネント内
<Link
href={siteConfig.links.twitter}
target="_blank"
rel="noopener noreferrer"
>
Twitter
</Link>
注意点
WARNING
Next.js 13以降では、<Link>
コンポーネントの直接の子として<a>
タグを使用するとハイドレーションエラーが発生する可能性があります。代わりにtarget
とrel
属性を<Link>
に直接渡してください。
セキュリティ警告
target="_blank"
を使用する場合は常にrel="noopener noreferrer"
を追加してください。これがないと、新しいタブから元のページにアクセス可能になり、セキュリティリスクが生じます。
まとめ
Next.jsでリンクを新しいタブで開く方法は、使用しているNext.jsのバージョンとリンクの種類によって異なります:
- 外部リンクには通常の
<a>
タグを使用 - Next.js 13以降では
Link
コンポーネントに直接target="_blank"
を指定 - 古いバージョンでは
legacyBehavior
とpassHref
を使用
常にセキュリティのためにrel="noopener noreferrer"
属性を追加することを忘れないでください。