多言語サイトを作ったのに、狙った国の検索結果に出てこない。日本語で検索したのに英語版が表示される。こうした問題の多くは hreflang の設定が原因です。
この記事では hreflang の役割とSEO上の重要性、3つの実装方法、そして実際に自社サイトで見つかった誤実装とその修正内容までを解説します。
hreflangタグとは何か
hreflangタグとは、HTMLの link 要素で使用される属性で、あるページの対象言語や地域を検索エンジンに伝えるためのものです。同一または類似の内容を異なる言語や地域向けに用意している場合、それぞれのページにこのタグを指定することで、検索エンジンがユーザーの言語や地域に適したページを検索結果に表示できるようになります。
Appleの公式サイトで、米国のユーザーには米国版が、スペインのユーザーにはスペイン語版が表示されるのは、hreflangの設定によるものです。
検索エンジンはhreflangを手がかりに、あるページの他言語版・他地域版を理解します。GoogleとYandexはこのタグを重視して配信に活用しており、Bingも重要度はやや低いものの公式に実装を推奨しています。
設定しない場合、検索エンジンは各言語版の関連性を正しく把握できず、ユーザーの地域にそぐわない言語のページが検索結果に出る恐れがあります。望まない言語のページを開いた訪問者はすぐ離脱するため、直帰率が上がり体験を損ないます。さらに、同じ内容のページが複数あると重複コンテンツと見なされるリスクもあります。
SEOにおける重要性
重複コンテンツの回避
言語違いとはいえ内容がほぼ同一のページが複数ある場合、hreflangがないとGoogleはそれらを重複コンテンツとみなし、どれか一つのURLだけをインデックスして他を除外してしまう可能性があります。
正しい言語・地域ターゲティング
日本語の検索クエリに対して英語ページが表示されたり、イギリスのユーザーに米国向けページが表示されたりすると不便です。hreflangを実装しておけば、Googleは各言語版の対応関係を理解し、ユーザーの地域と言語に合致したページを表示しようとします。
検索結果への影響
ユーザーが自分の言語で書かれたページに誘導されれば、内容を理解しやすく満足度が上がるため、離脱せずサイトに留まる傾向が高まります。直帰率の低下や閲覧時間の伸びといったエンゲージメントの改善は、検索順位にも良い影響を及ぼすと考えられています。
3つの実装方法
hreflangの指定方法は主に3つあり、サイトの構成や扱うコンテンツに応じて使い分けます。
HTMLのhead内に記述する
もっとも基本的な方法です。多言語版のそれぞれのページに、他の言語版へのリンクを追加します。
<link rel="alternate" hreflang="en-us" href="https://website.com/en" />
<link rel="alternate" hreflang="es-es" href="https://website.com/es" />rel="alternate" は指定したURLが代替ページであることを示し、hreflang には言語(と地域)をISOコードで指定します。各ページには自分自身と他の言語版すべてを網羅するリンクを入れる必要があります。
いずれの言語にも当てはまらないユーザー向けに、hreflang="x-default" を指定したリンクを含めることも推奨されます。
実装が直感的でCMSプラグインも対応しやすい一方、言語数が増えるほどHTMLの記述量が増え、DOMが肥大化します。
HTTPヘッダーを使う
PDFや画像などHTML内にタグを埋め込めないコンテンツには、HTTPレスポンスヘッダーのLinkヘッダーで指定します。
Link: <https://example.com/report-en.pdf>; rel="alternate"; hreflang="en",
<https://example.com/report-ja.pdf>; rel="alternate"; hreflang="ja"カンマ区切りで複数指定でき、非HTMLコンテンツでも対応関係を伝えられます。ただし言語バリエーションが多いとヘッダーが長くなりすぎるため、大規模サイトでは次のサイトマップ方式も検討してください。
XMLサイトマップで指定する
多数のページを一括管理したい場合や、HTML内にコードを増やしたくない場合の方法です。
<url>
<loc>https://example.com/en/</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/" />
<xhtml:link rel="alternate" hreflang="es" href="https://example.com/es/" />
</url>各ページ自身も含めて記載する点に注意してください。言語バージョンが非常に多いサイトでも効率的に実装できますが、記述量自体は増えるため自動生成ツールの活用が現実的です。
言語コードと地域コードの書き方
hreflangで最も多い間違いはコードの誤りです。ここは仕様が決まっているので、正確に書けば済みます。
言語コードは ISO 639-1 の2文字、地域コードは ISO 3166-1 alpha-2 の2文字 を使います。書式は
言語 または 言語-地域 で、地域だけを単独で指定することはできません。国名コードと取り違えない
日本語は
ja です。jp ではありません。国名コードと混同しやすいところで、実際に間違えているサイトをよく見かけます。よく使う言語コードは次のとおりです。
- 日本語
ja/ 英語en/ 中国語zh/ 韓国語ko
- フランス語
fr/ ドイツ語de/ スペイン語es/ イタリア語it
- ポルトガル語
pt/ ロシア語ru/ タイ語th/ ベトナム語vi
- インドネシア語
id/ アラビア語ar/ ヒンディー語hi
取り違えが起きやすいのは、日本語の
ja(jp ではない)、中国語の zh(cn ではない)、ギリシャ語の el(gr ではない)、ウクライナ語の uk(ua ではない)あたりです。いずれも「国名コードのほうを書いてしまう」という同じ形の誤りです。地域コードは必要なときだけ付ける
en-us と en-gb のように地域まで分けるのは、同じ言語で内容を出し分けている場合だけです。価格を通貨単位で変えている、法的表記が国ごとに違う、といったケースが該当します。英語版が1つしかないのに
en-us と書くと、米国以外の英語圏ユーザーに配信されにくくなります。単に「英語版」であれば en と書くのが正解です。地域を足すかどうかは、ページの中身が実際に国ごとに違うかどうかで決めてください。翻訳しただけで内容が同じなら、言語コードだけで十分です。
中国語は地域ではなく文字体系で指定する
中国語だけは例外で、文字体系(script)で指定するのが正しい書き方です。
- 簡体字 →
zh-Hans
- 繁体字 →
zh-Hant
zh-CN(中国本土)や zh-TW(台湾)でも動作はします。ただし繁体字は台湾だけでなく香港・マカオでも使われるため、地域で切ると香港からの訪問者が取りこぼされます。文字体系で指定すれば地域を問わず正しく配信されます。Hans Hant の先頭は大文字で書きます。仕様上は大文字小文字を区別しませんが、慣例に合わせておくほうが後から読む人が迷いません。日本企業のサイトで中国語対応を入れる場合、簡体字と繁体字の2種類を用意することが多くなります。この2つを地域コードで切るか文字体系で切るかで、届く範囲が変わります。
x-default をどこに向けるか
x-default は、用意しているどの言語にも当てはまらない訪問者に対して、どのページを見せるかを指定するものです。省略しても動きますが、指定しておくほうが安全です。指定先として妥当なのは次のどちらかです。
- 言語選択ページ — 訪問者に言語を選ばせる中間ページがあるなら、そこを指定する
- 主要言語版 — 中間ページが無いなら、実質の既定となる言語版を指定する
当社のサイトには言語選択ページが無いため、日本語版を
x-default に指定しています。日本語版が原本で、他言語版はそこから生成されているためです。書き方は他の hreflang と同じ形式です。
<link rel="alternate" hreflang="ja" href="https://ai-translate.com/guide/" />
<link rel="alternate" hreflang="en" href="https://en.ai-translate.com/guide/" />
<link rel="alternate" hreflang="fr" href="https://fr.ai-translate.com/guide/" />
<link rel="alternate" hreflang="x-default" href="https://ai-translate.com/guide/" />x-default に指定したURLは、その言語版としての hreflang も併せて書きます。上の例では日本語版が ja と x-default の両方から参照されている形です。これは重複ではなく、仕様上の正しい書き方です。よくある実装ミス
- 自己参照を忘れている:各ページには自身を指すhreflangリンクも必ず含める必要があります
- 相互参照(リターンタグ)の不足:ページAからBへ設定したら、B側からもAへ設定しなければなりません
- 言語コード・地域コードの誤り:言語はISO 639-1の2文字、地域はISO 3166-1の2文字で正確に記述します
- URLの指定ミス:相対パスではなく絶対パス(フルURL)を使う必要があります
- canonicalとの不整合:すべての言語ページが単一ページをcanonical先にしていると、検索エンジンはそのページだけをインデックスし、他言語版を表示しなくなります
設定した後の確認方法
hreflang は「書いたつもり」で終わりやすい実装です。当社自身がそうでした。公開したあとに必ず確認してください。
ソースを直接見るのが最も確実
記事ページを1つ開いてソースを表示し、
alternate の行を探します。確認するのは次の3点です。- href がルートURLではなく、そのページ自身のパスになっているか
- 自分自身を指す行(自己参照)が入っているか
- 対応している言語がすべて列挙されているか
トップページだけを見て「対応済み」と判断しないでください。当社の誤実装も、トップページでは正しく見えていました。壊れていたのは記事ページと料金ページのほうです。
相互参照を往復で確かめる
日本語版から英語版へのリンクがあるなら、英語版から日本語版へのリンクも必要です。片方向だけの指定は検索エンジンに無視されます。
日本語ページのソースで英語版のURLを確認し、そのURLを開いて、日本語ページへ戻るリンクが入っているかを見ます。この往復確認を数ページぶんやれば、設定が構造として正しいかどうかは判断できます。
言語切り替えのUIが動くことと、hreflang が正しいことは別の話です。切り替えボタンが機能していても hreflang がルートURL固定、という組み合わせは珍しくありません。
目視ではなくテストで固定する
Search Console の URL 検査で個別ページの認識状況は確認できますが、hreflang の専用レポート(インターナショナル ターゲティング)は廃止されているため、一覧で監視することはできません。ページ数が増えるほど目視は現実的でなくなります。
当社では、メタ情報を組み立てる処理を
buildPageMeta という純粋関数に切り出し、単体テストで固定しています。検証している内容は次のとおりです。- 日本語の自己参照・英語版・フランス語版・
x-defaultが、ルートではなくページ単位のURLで出ること
- 未解決の動的ルートでは canonical も alternate も出さないこと
誤った canonical を出すくらいなら出さないほうが安全なので、後者もテストで固定しました。
こうしたメタ情報は、一度直しても改修のたびに壊れます。人が毎回目視で守り続けるのは無理があるので、テストで固定してしまうのが結局いちばん安く済みます。
自社サイトで実際に起きていた誤実装
ここまでは一般論ですが、こうしたミスは実際に起こります。当社の ai-translate.com 自身が、つい先日まで誤った実装をしていました。
問題は3つありました。
第一に、すべてのページが英語版・フランス語版の「ルートURL」を指していました。記事ページからも料金ページからも、alternate の href が一律で
https://en.ai-translate.com になっていたのです。ページ単位の対応が取れていないため、検索エンジンから見れば意味をなさない指定でした。第二に、日本語版の自己参照がありませんでした。上に挙げた「自己参照を忘れている」を、解説している当人がやっていたわけです。
第三に、x-default も指定していませんでした。
さらに悪いことに、この時点でサイトには canonical タグ自体が1つも出力されていませんでした。hreflang と canonical は組み合わせて機能するため、片方が欠けている状態では効果が期待できません。
どう直したか
修正は、メタ情報の生成を1か所の関数に集約するところから始めました。それまでは共通コンポーネントの中に直接書かれていて、テストもできない状態でした。
現在は、各ページのパスを受け取って以下を返す純粋関数になっています。
- 日本語版の自己参照(そのページ自身の絶対URL)
- 英語版・フランス語版の同一パス(ルートではなくページ単位)
- x-default(日本語版と同じURL)
あわせて自己参照canonicalも全ページに出力するようにしました。動的ルートでパスが未解決の場合は canonical も alternate も出力しない、という分岐も入れています。誤ったcanonicalを出すくらいなら出さないほうが安全だからです。
教訓
この一件から得た教訓は2つあります。
ひとつは、hreflangは「設定してあるか」ではなく「ページ単位で正しいか」を見なければ意味がないことです。当社のサイトにはalternateタグが確かに出力されていました。ソースを見れば「hreflang対応済み」に見えます。しかし中身はルートURL固定で、対応関係を一切表していませんでした。
もうひとつは、メタ情報の生成をテストできる形にしておくことです。共通コンポーネントに直接書かれていると、誰も検証しないまま何年も間違ったまま動き続けます。純粋関数に切り出しておけば、「x-defaultが出ているか」「自己参照が入っているか」を自動テストで固定できます。
多言語サイトを運用しているなら、一度ご自身のサイトのソースを開いて、記事ページの alternate が本当にその記事の他言語版を指しているか確認してみてください。ルートURLになっていないでしょうか。
hreflang以外も含めた多言語SEOの実装事故と、自社サイトを10分で診断する手順は多言語サイトのSEO実装ガイドで扱っています。
そもそも翻訳・ローカライズ・トランスクリエーションのどれを選ぶべきかという判断は翻訳、ローカライズ、トランスクリエーションの違いって何?で整理しています。

