Next.js(ページルーター)v16で代替言語バージョンをリンクする方法
検索エンジン向けに言語の代替バージョンをリンクする
問題
ウェブサイトが複数の言語で同じコンテンツを提供する場合、検索エンジンはそれらの関係を理解せずに各バージョンの別々のURLに遭遇します。フランス語ユーザーが検索すると、フランス語版が存在するにもかかわらず、英語版の方が上位にランク付けされる可能性があります。同様に、英語ページとそのフランス語訳は、連携した代替版ではなく、競合する重複として扱われる可能性があります。これらの言語バージョンを接続する明示的な信号がなければ、検索エンジンはユーザーの言語設定に基づいて最適なバージョンを確実に提供することができず、ランキング権限の断片化と不適切なユーザーエクスペリエンスにつながります。
解決策
各ページのheadセクションにhreflang属性を持つlink要素を追加し、ページ自体を含むすべての言語バージョンをリストアップします。各ページバリアントには、利用可能なすべての言語バージョンを参照する同一のリンクセットを含める必要があります。この双方向リンキングにより、検索エンジンはページを重複ではなく翻訳として認識し、ブラウザの設定や検索コンテキストに基づいて正しい言語バージョンをユーザーに提供できるようになります。
ステップ
1. 代替言語リンクを生成するコンポーネントを作成する
ページメタデータを変更するためにnext/headからHeadコンポーネントをインポートします。useRouterフックを介してロケール情報にアクセスし、利用可能なすべての言語バージョンのリンクを構築します。
import Head from "next/head";
import { useRouter } from "next/router";
interface AlternateLinksProps {
path?: string;
}
export default function AlternateLinks({ path }: AlternateLinksProps) {
const router = useRouter();
const { locales, locale: currentLocale, asPath } = router;
const canonicalPath = path || asPath;
if (!locales) {
return null;
}
return (
<Head>
{locales.map((locale) => (
<link
key={locale}
rel="alternate"
hrefLang={locale}
href={`${process.env.NEXT_PUBLIC_SITE_URL}/${locale}${canonicalPath}`}
/>
))}
</Head>
);
}
このコンポーネントはルーターから利用可能なロケールを取得し、すべてのページに対して動的にlink要素を生成します。
2. 翻訳がある各ページにコンポーネントを追加する
複数の言語で存在する各ページコンポーネントにAlternateLinksコンポーネントを含めます。
import AlternateLinks from "@/components/AlternateLinks";
export default function AboutPage() {
return (
<>
<AlternateLinks />
<main>
<h1>About Us</h1>
</main>
</>
);
}
このコンポーネントは、各ページに代替リンクの完全なセットを含めることを保証し、すべてのバリアントが互いに参照するという要件を満たします。
3. 現在のロケールに対する自己参照リンクを含める
すべてのページには、自身の言語を示す自己参照hreflangタグを含める必要があります。このコンポーネントは、現在のロケールを含むすべてのロケールを反復処理することでこれを処理します。
export default function AlternateLinks({ path }: AlternateLinksProps) {
const router = useRouter();
const { locales, asPath } = router;
const canonicalPath = path || asPath;
if (!locales) {
return null;
}
return (
<Head>
{locales.map((locale) => (
<link
key={locale}
rel="alternate"
hrefLang={locale}
href={`${process.env.NEXT_PUBLIC_SITE_URL}/${locale}${canonicalPath}`}
/>
))}
</Head>
);
}
各ページには、他のバージョンのタグと共に自身を指すhreflangタグが含まれるようになりました。
4. x-defaultフォールバックリンクを追加する
ユーザーの言語が利用できない場合に表示するバージョンを指定するx-defaultリンクを追加します。
export default function AlternateLinks({ path }: AlternateLinksProps) {
const router = useRouter();
const { locales, defaultLocale, asPath } = router;
const canonicalPath = path || asPath;
if (!locales || !defaultLocale) {
return null;
}
return (
<Head>
{locales.map((locale) => (
<link
key={locale}
rel="alternate"
hrefLang={locale}
href={`${process.env.NEXT_PUBLIC_SITE_URL}/${locale}${canonicalPath}`}
/>
))}
<link
rel="alternate"
hrefLang="x-default"
href={`${process.env.NEXT_PUBLIC_SITE_URL}/${defaultLocale}${canonicalPath}`}
/>
</Head>
);
}
x-defaultリンクは、言語設定が一致しないユーザーをデフォルトロケールに誘導します。