hreflang 設定六大地雷——為什麼整組標籤會被 Google 忽略

翻譯明明做好了,英文頁、日文頁一個都沒少,可是 Google 還是把繁中版推給美國人,把英文版塞給台灣搜尋者。國外客戶點進來看到一頁不認得的文字,三秒就關掉;你辛苦翻好的頁面,曝光卻一直掛在錯的市場。

問題九成不出在內容,而出在 hreflang 這個標籤——它是寫在頁面裡、告訴搜尋引擎「這頁是哪個語言、給哪個地區看」的對照宣告。設定對了,Google 會把對的版本端到對的人面前;設定錯了,整組宣告會被當成無效,直接忽略,你等於白標。

麻煩的是,hreflang 出錯的方式很固定,幾乎每個多語系網站都栽在同一批地方:少寫了指向自己那一行、A 頁指向 B 頁但 B 頁沒回指、語言代碼順序顛倒、或是拿一份早就被 Google 淘汰的報告在驗證。先把這幾個最常見的錯一個一個拆開,講清楚為什麼會壞、怎麼修,最後再帶你用現在還有效的方法驗證一遍。

為什麼 hreflang 一錯,整組就會被忽略

hreflang 不是「有寫就有分」的加分項,它更像一份契約——每個版本都要在契約上簽名、而且彼此都要認得對方,少一個簽名,整份契約就作廢。

這跟很多人的直覺不一樣。你可能以為標籤是獨立計分的,這頁寫對就這頁有效、那頁漏了頂多那頁沒效。實際上 Google 是把一整組語言版本當成一個「叢集」來判讀的——它要看到這組裡每個成員都互相承認,才會相信這是刻意設計的多語系對應,而不是幾個剛好長得像的頁面在互搶排名。

所以 hreflang 的錯誤幾乎都是「關係錯誤」,不是「拼字錯誤」。一個代碼寫錯、一個回指漏掉,受影響的往往不只那一頁,而是整組對應一起失效。也正因為這樣,下面這幾個錯才特別值得逐一檢查——它們單看都是小事,卻足以讓你整套多語系設定形同虛設。先從最高頻、也最容易忽略的那個講起。

第一名,忘了讓每個頁面指向自己

最常見、也最容易被跳過的錯,就是漏掉「自我參照」那一行。每個頁面除了標出其他語言版本,也必須有一行 hreflang 指向自己

很多人寫 hreflang 的時候,心裡想的是「告訴 Google 還有別的版本」,於是繁中頁只列了英文版、日文版的網址,唯獨忘了把繁中版自己也寫進去。問題就出在這裡——Google 在比對這組叢集時,需要每一頁都明確聲明「我是這個語言版本」。少了這一行,爬蟲在清點成員時會發現對不齊——別的頁面都說有繁中版,繁中頁自己卻不認帳,這組關係就被判定不完整。

修正方式很單純,但要養成習慣。假設你有繁中(zh-TW)、英文(en)、日文(ja)三個版本,那麼每一頁的標籤組都要完整列出這三個版本,包含自己那一個。以繁中頁為例,它的 <head> 裡應該同時有指向繁中、英文、日文的三行:

<link rel="alternate" hreflang="zh-TW" href="https://example.com/zh-tw/" />
<link rel="alternate" hreflang="en" href="https://example.com/en/" />
<link rel="alternate" hreflang="ja" href="https://example.com/ja/" />Code language: HTML, XML (xml)

英文頁、日文頁也都各自放上一模一樣的這三行。換句話說,三個版本的 hreflang 區塊內容應該長得幾乎一樣,差別只在每頁的 canonical 各自指向自己。只要記住「自己也是成員之一」,這個錯就不會犯。

第二名,A 頁指向 B 頁,B 頁卻沒回指 A

第二個高頻錯誤是「沒有雙向配對」——你的繁中頁宣告了有英文版,但英文頁卻沒回頭宣告有繁中版。這種單向關係,Google 一律不認。

hreflang 的配對是互惠的——它要兩邊都點頭,才確認你們是同一內容的不同語言版本。打個比方,這像兩個人交換名片,你把名片遞給對方,對方手上卻沒有你的名片,那這份「我們認識」的關係在 Google 眼裡就不成立。只要回指(return tag)缺了一邊,這組宣告就會被忽略,而且常常是整組一起失效,不是只壞掉漏掉的那一邊。

這個錯特別容易在「事後追加語言」時發生。網站原本只有繁中和英文,後來要新增日文版,工程師很勤快地在日文頁標好了「有繁中、有英文」,卻忘了回頭去繁中頁和英文頁,補上「我們也有日文版」這一行。結果日文頁單方面伸出手,舊頁面沒接,配對失敗。

修正的關鍵在於「成組更新」這四個字。每次新增或修改一個語言版本,都要回去把同一叢集裡的所有頁面一起改,確保每一頁都列了彼此、也都回指。如果你的網站頁面很多、手動維護容易漏,這時候改用 XML sitemap 來集中管理 hreflang 會省事得多——所有對應關係寫在一個檔案裡,比較不會東漏一頁西漏一頁。實作方式後面會再談,先記住一個原則,hreflang 只要有人沒回指,就等於沒設。

第三名,語言代碼格式或順序寫錯

第三個常見地雷是代碼本身寫錯——順序顛倒、用了不存在的縮寫、或把地區當成語言。代碼一錯,Google 無法辨識,這一行就跟沒寫一樣。

hreflang 的值有它的硬規則,記住兩個標準就不會錯:

  1. 語言碼用 ISO 639-1,兩個小寫英文字母,例如 zhenjafr
  2. 地區碼(選填)用 ISO 3166-1 Alpha-2,兩個大寫英文字母,例如 TWUSJP
  3. 兩者用連字號接成「語言-地區」,例如 zh-TWen-USen-GB

聽起來簡單,但實際翻車的地方很集中,常見的有這幾種:

  • 順序顛倒:寫成 us-en,但正確是 en-US。語言永遠在前、地區永遠在後。
  • 用了不存在的代碼:最經典的是把英國寫成 en-ukuk 不是英國的地區碼,英國的正確寫法是 en-GB(GB 來自 Great Britain)。同樣地,zh-CH 也是錯的,沒有這個組合。
  • 只寫地區、漏了語言:直接寫 tw 想代表台灣。但 hreflang 的第一段一定是語言,不能單獨只給地區碼;台灣繁中要寫成 zh-TW,不是 tw
  • 繁簡中文搞混:台灣繁中用 zh-TW,香港繁中用 zh-HK,中國大陸簡中用 zh-CN。如果你想用書寫系統來區分,也可以用 zh-Hant(繁體)和 zh-Hans(簡體),但別把 zh-Hantzh-CN 混在同一套邏輯裡用。

修正方法就是逐行對照這兩個標準檢查一遍。代碼大小寫雖然 Google 通常能容錯,但養成「語言小寫、地區大寫」的習慣,自己看 code 時也比較不會看花。

第四名,用相對網址或指向打不開的頁面

第四個錯比較隱蔽,標籤格式都對,但 href 裡填的網址有問題——用了相對路徑,或指到一個根本回不了 200 的頁面。這種錯不會讓你一眼看出,卻會讓整組 hreflang 默默失效。

先說相對網址。有些人圖方便,href 直接寫 /en/ 這種相對路徑。但 hreflang 的網址必須是包含 https:// 的完整絕對路徑,因為搜尋引擎在跨頁、跨網域比對時,相對路徑會解析錯誤,找不到正確的對應頁。一定要寫成 https://example.com/en/ 這種完整網址。

再來是更關鍵的一點。hreflang 指向的每一個網址,都必須是能正常回傳 200 狀態的活頁面,如果其中一個版本的網址是下面這幾種狀況:

  • 是 404(頁面不存在或網址打錯)
  • 被 301/302 轉址到別處
  • 設了 noindex
  • 被 robots.txt 擋住

只要 hreflang 清單裡有任何一個網址落在上面這幾種狀況,Google 對那整組叢集的判讀就會出問題,常常是整組一起失效,不是只忽略壞掉的那一個。這也是為什麼「網站改版、URL 結構動過」之後最容易出包——舊的 hreflang 還指著舊網址,舊網址卻已經被轉址或下架了。

修正的做法很簡單,每次調整網址、搬移頁面、或設定轉址之前,先想到「有沒有 hreflang 還指著這個網址」,把對應清單一起更新。網址改了,hreflang 也要跟著改,這兩件事要綁在一起做。

第五名,hreflang 和 canonical 互相打架

第五個是比較進階、但殺傷力很大的錯——hreflang 跟 canonical 標籤給了搜尋引擎矛盾的指令。兩個標籤分工不同,搞混了就會互相抵消。

先把分工講清楚。canonical 是用來合併「同一語言內」的重複頁,例如同一頁因為排序參數、追蹤參數而產生好幾個網址,canonical 告訴 Google「這幾個裡面,這個才是正主」。而 hreflang 是用來連結「不同語言/地區」的對等版本,它的邏輯恰好相反——它說「這幾頁都是有效的,只是給不同人看的」。

最常見的打架是這樣發生的。有人想表達「中文版對應英文版」,就把繁中頁的 canonical 指向了英文頁。這下慘了——canonical 的意思是「繁中頁是英文頁的重複版,請忽略繁中頁」,於是 Google 真的就不索引繁中頁了。你本來想做的是「對應」,結果做成了「請刪掉我的繁中版」。

正確做法是讓兩個標籤各司其職:

  • 每個語言版本的 canonical 都指向自己(繁中頁的 canonical 指繁中頁,英文頁的 canonical 指英文頁)。
  • 跨語言的對應,全部交給 hreflang 處理,不要用 canonical 去跨語言互指。

把這條規則記成一句話就好——canonical 管「同語言的重複」,hreflang 管「跨語言的對應」,兩者井水不犯河水。順帶一提,同樣的衝突也會發生在自動轉址上——如果網站依使用者所在地強制把訪客轉到某個語言版本,Google 爬蟲可能只看得到單一版本,其他語言根本抓不到。要避免,就別硬性轉址,讓使用者自己選,並靠 hreflang 加上後面要講的 x-default 來引導。

第六名,沒設 x-default 讓預設頁失聯

第六個錯比較小,但補起來成本很低、效益不錯,那就是忘了設 x-default。x-default 是一個特殊的 hreflang 值,用來指定「當使用者的語言和地區都對不上任何現有版本時,要顯示哪一頁」。

舉個情境,你的網站有繁中、英文、日文三版,這時一位用韓文瀏覽器、人在泰國的使用者搜到了你。他的語言(韓文)和地區(泰國)都不在你的清單裡,Google 該推哪一頁給他?如果你有設 x-default,Google 就會把你指定的那個「通用落點」端給他;沒設的話,Google 只能自己猜,猜錯的機率不低。

x-default 通常指向兩種頁面之一,一個是語言選擇頁(讓使用者自己挑),另一個是通用的全球首頁(例如英文版首頁)。它的寫法不需要地區碼,像這樣:

<link rel="alternate" hreflang="x-default" href="https://example.com/" />Code language: HTML, XML (xml)

這裡要避開一個常見誤會——x-default 不是用來宣告「預設語言」的。很多人以為把 x-default 指向英文版,就等於告訴 Google「英文是我的主語言」,這是錯的。x-default 處理的只有「沒有對應版本可選」這一種情況,它指向的頁面應該是個對誰都堪用的「萬用落點」,而不是某個高度在地化的特定語言頁。設定的時候,也記得讓這個 x-default 網址自己的 canonical 指向自己、而且能正常回傳 200,規則跟其他 hreflang 網址一樣。

三種實作方式選一種就好,別混用

把上面六個錯避開之後,還有一個影響成敗的決定,就是你要把 hreflang 放在哪裡。Google 接受三種放法,效力完全相同,重點是選一種、確實做好,不要混用

三種方式各有適合的場景:

實作方式怎麼放適合誰
HTML <head>在每頁的 <head> 加上 <link rel="alternate" hreflang="...">頁數不多(數十到數百頁)、用 WordPress 等 CMS、想要最直觀好驗證的網站
XML Sitemap在 sitemap 用 <xhtml:link> 標出各語言版本頁數多、語言多、想集中管理避免逐頁漏標的大型網站
HTTP Header透過伺服器回應標頭傳遞PDF、DOC 等非 HTML 檔案

為什麼強調別混用?因為一旦你同時在 HTML 和 sitemap 兩個地方都寫了 hreflang,又寫得不一致,Google 會收到兩套打架的資訊,反而更難判讀,除錯時也得兩邊對。挑一種當作唯一的真相來源,維護起來最乾淨。

實務上的建議很簡單。如果你是中小型網站、頁數在數百頁以內,用 HTML <head> 最直接,改起來看得到、驗證也快。如果語言版本多、頁面成千上萬,逐頁手動維護遲早會漏,這時候把 hreflang 全部收進 XML sitemap 集中管理,會比追著每一頁改省事得多。

設定完怎麼驗證?別再用那份已淘汰的報告

這是最多教學沒更新、卻最該講清楚的一點——Google Search Console 裡那個「指定國際目標」(International Targeting)報告已經被淘汰了。它過去是大家驗 hreflang 的第一站,會列出「缺少回指標籤」之類的錯誤——但這個報告已經下架,再照舊教學去左側選單找它,你只會撲空。

那現在該怎麼驗證?方法其實更分散、但也更貼近實況,分幾個層次來做:

  1. 先用 Search Console 的「網址審查」工具。貼上某個語言頁的網址,看 Google 對這頁的索引狀態、以及它認定的 canonical 是不是你預期的那一個。如果 Google 選的 canonical 跟你設的不一致,多半就是前面講的 canonical 打架,或頁面回傳了非 200 狀態。
  2. 看「網頁索引」(Pages)報告。雖然沒有專屬的 hreflang 分頁了,但這裡會透露替代網址回傳非 200、被 noindex、或無法擷取之類的問題,這些都是讓 hreflang 失效的常見根因。
  3. 配一個爬蟲工具做全站健檢。像 Screaming Frog 這類 SEO 爬蟲有專門的 hreflang 檢視,能一次掃出全站哪些頁面缺回指、代碼寫錯、或網址對不上,這是手動逐頁看做不到的覆蓋率。
  4. 單頁快驗用免費的 hreflang 測試工具。貼上一個網址,它會把這頁所有 hreflang 標籤列出來、逐一驗證格式和回指,適合上線後針對重點頁做抽查。

驗證的節奏也要抓對。hreflang 改動之後,Google 不是即時生效的,通常要等它重新爬過、重新索引,所以設定完別急著隔天就下結論,給它兩到四週,再回頭用上面這幾個方法複查。

另外提醒一個排查方向。hreflang 是「建議」不是「強制指令」。如果你的頁面實際內容是英文,卻硬標成 hreflang="zh-TW",Google 會以實際內容為準、直接忽略這個標籤。所以驗證時除了看標籤本身,也要確認頁面內容跟它宣告的語言真的一致——半翻譯、選單沒翻、機器翻譯品質太差的頁面,都可能讓 Google 對這組對應打折扣。

把 hreflang 當成一組關係來維護

hreflang 的難,從來不在單一標籤怎麼寫,而在它是一張需要「全體一致」的關係網。少一行自我參照、漏一個回指、動了一次網址沒同步更新——這些單看都是小疏忽,卻足以讓整套多語系設定靜悄悄地失效,而且失效時 Google 不會跳警告給你,頁面只是默默排在錯的市場。

所以與其把它當成上線前打勾的一次性任務,不如把它納入日常維護的清單:每次新增語言、每次搬頁面、每次改網址結構,都回頭問一句「這動作會不會弄壞某組 hreflang 的對應」。設定對的多語系網站,會讓對的內容自己走到對的人面前;而這一切的前提,只是把每個頁面之間的那層關係,老老實實地維持完整。