Next.js(Pages Router)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リンクは、言語設定が一致しないユーザーをデフォルトロケールに誘導します。