seonextjsindexing
Next.js多言語のcanonical/hreflang|言語跨ぎcanonicalを防ぐ実務チェックリスト
|
5 min read
多言語Next.jsで起きがちなcanonical/hreflang事故をチェックリスト化。言語跨ぎcanonical、URL正規化(スラッシュ/大小/パラメータ)の揺れ、rewrite由来の重複を潰し、ソース/サイトマップ/GSCで検証する。
目次
- 結論(Conclusion)
- 背景(Explanation)
- 実務手順(Practical Guide)
- 手順1:正しいURL形を決める(唯一の形)
- 手順2:基本は自己参照canonical
- 手順3:言語跨ぎcanonicalを絶対に避ける
- 手順4:登録対象ページはhreflangを揃える
- 手順5:canonical/hreflang/sitemapのURL表記を完全一致
- 手順6:パラメータを意図的に扱う
- 手順7:最短で検証する
- 失敗パターン(Pitfalls)
- チェックリスト(Checklist)
- FAQ
- Q1. 全言語を1つの正規URLに寄せてもいい?
- Q2. x-default は必要?
- Q3. 指定canonicalとGoogle選択canonicalがズレるのはなぜ?
- 内部リンク(Internal links)
- 参考(一次情報)
- 免責
Next.js多言語サイトでcanonical/hreflangはどう設定すれば事故らない?
結論(Conclusion)
一番危険なのは 言語を跨いだcanonical。
/ja/...が/en/...を正規URLにしてしまう(または逆)
これをやると、片側言語が重複扱いになって登録されないことがある。
安全な手順はこう。
- URL表記を正規化(スラッシュ/大小/パラメータ)
- 各言語ページは基本 自己参照canonical
- 登録対象ページは 相互hreflang を揃える
- ソース/サイトマップ/GSC URL検査で整合を確認
背景(Explanation)
canonical/hreflangはシグナル。 シグナルが矛盾するとGoogleは別のcanonicalを選ぶ。
Next.js多言語で矛盾が出る原因はだいたいこれ。
- 末尾スラッシュ等でURL候補が増える
- canonical/hreflang/sitemapが別ロジックでURLを作っている
- rewriteで複数URLが発見される
- 言語ページの中身がほぼ同じでクラスタ化
対策は“テクニック”ではなく URL正規化の一貫性。
実務手順(Practical Guide)
手順1:正しいURL形を決める(唯一の形)
決める:
- 末尾スラッシュ有無
- 小文字固定か
- 許可するクエリパラメータ
判断基準:
- 正規化はrewriteよりredirectが安全(候補URLを減らす)。
手順2:基本は自己参照canonical
各言語ページは通常、自分自身をcanonicalにする。
全言語を1言語に寄せるのは、意図的に統合したいときだけ。
手順3:言語跨ぎcanonicalを絶対に避ける
悪い例:
/ja/product/→ canonical/en/product/
結果:
- JAが重複扱いになり登録されない/遅れる。
手順4:登録対象ページはhreflangを揃える
- 各ページが全言語版(+必要なら
x-default)を持つ - 相互リンク(A→B、B→A)
- noindexページは入れない
手順5:canonical/hreflang/sitemapのURL表記を完全一致
よくある揺れ:
- canonicalはスラッシュ無し、hreflangはスラッシュ有り
- hreflangだけパラメータ付き
判断基準:
- URL生成は1つのヘルパーに集約し、canonical/hreflang/sitemapで共通利用。
手順6:パラメータを意図的に扱う
utm_*:canonicalはクリーンURL?page=2:登録するかしないか、先に意思決定
手順7:最短で検証する
代表3ページ(トップ/カテゴリ/記事)で:
- ソース:canonical + hreflang(全ロケール)
- GSC URL検査:指定canonical vs Google選択canonical、言語別登録状態
失敗パターン(Pitfalls)
- rewriteで複数URLが発見される(redirectで正規化していない)
- 言語ページがほぼ同一でクラスタ化
- trailingSlash設定とURL生成がズレる
- hreflangが相互になっていない/不足
チェックリスト(Checklist)
- [ ] URLの唯一の形を決めた(スラッシュ/大小/パラメータ)
- [ ] 可能な限りredirectで正規化した
- [ ] 各言語ページが自己参照canonical
- [ ] 言語跨ぎcanonicalがない
- [ ] hreflangが登録対象ページに入っている
- [ ] hreflangが相互リンクになっている
- [ ] canonical/hreflang/sitemapのURL表記が一致
- [ ]
utm_*はクリーンURLへcanonical - [ ] 機能パラメータの登録方針が決まっている
- [ ] ソース/サイトマップ/GSCで検証した
FAQ
Q1. 全言語を1つの正規URLに寄せてもいい?
統合したいならあり。ただし多言語として成立させたいなら、自己参照canonicalの方が安全。
Q2. x-default は必要?
必須ではないが、言語選択ページや汎用ページがあるなら有効。重要なのは相互hreflang。
Q3. 指定canonicalとGoogle選択canonicalがズレるのはなぜ?
URL表記の揺れ、rewrite由来の重複、言語ページの近似などでシグナルが矛盾しているから。まず一貫性を直す。
内部リンク(Internal links)
- 親記事(Hub):インデックス(Indexing):まずはここから
- 関連記事:
参考(一次情報)
- Google: canonical / 重複URLの統合: https://developers.google.com/search/docs/crawling-indexing/consolidate-duplicate-urls
- Google: 多言語ページ(hreflang): https://developers.google.com/search/docs/specialty/international/localized-versions
免責
インデックスは確率的です。改善はできても、全URLの登録を強制はできません。