先把結論放在最前面:多語系網站的非英語流量起不來,十之八九不是內容或關鍵字的問題,而是每個語言版本的 canonical 被寫死成指向英文首頁。這一個標籤寫錯,等於主動請 Google 忽略你所有的在地版本。修正的核心只有兩句話,每個語言版本的 canonical 要指向自己,再用雙向的 hreflang 互相指認,兩件事缺一不可。這篇我們用一個真實的慘案,把 canonical 指錯會發生什麼、以及 canonical 與 hreflang 到底怎麼搭配,講到你能直接照做。

多語系 canonical 的錯誤與正確對照:錯誤為所有語言版本 canonical 都指向英文首頁,正確為每個語言自我 canonical 並用 hreflang 互指
多語系 canonical:錯誤 vs 正確

1. 一個把所有語言版本都指向英文首頁的慘案

根據我們的服務經驗,這類問題的共通點是:網站表面看起來都正常,流量報表卻異常地安靜。我們曾協助分析一款電子簽章 SaaS 的多語系網站,對方在台灣、日本、德國都有在地化的版本,內容也翻得很用心,從專有名詞到範例都照市場調整過。但流量報表就是很怪,非英語市場的自然搜尋幾乎起不來,日文與德文版的曝光量長期維持在個位數。掃過原始碼才發現問題,所有語言版本,包括繁中的 /zh-tw/、日文的 /ja/、德文的 /de/,它們的 canonical 標籤全部指向同一個英文首頁。

1.1 canonical 到底在回答什麼問題

canonical 這個標籤的作用,是告訴 Google「這一頁的權威版本是哪一個網址」。它原本是設計來收斂重複內容的,例如同一篇文章同時掛在兩個網址底下,你用 canonical 指定其中一個為正版,Google 就把權重集中過去。問題是,這個機制一旦套錯對象,殺傷力也同樣大。當繁中頁的 canonical 指向英文首頁,你等於親口跟 Google 說:「繁中這頁不是正版,英文首頁才是。」Google 照做,把繁中、日文、德文頁全部當成英文首頁的重複內容,索引時直接略過,權重全數集中到英文版。

1.2 為什麼這種錯特別難被發現

我們在實務上看過這類問題拖很久才被抓出來,原因是頁面在瀏覽器裡看起來一切正常。內容顯示、語言切換、選單連結都沒問題,肉眼完全看不出異常。canonical 藏在 <head> 裡,除非你主動去看原始碼或用爬蟲工具掃描,否則不會察覺。更棘手的是,很多網站是用同一套模板產生所有語言頁,模板裡的 canonical 被工程師寫死成首頁網址,結果一錯就是全站錯,而且錯得整齊劃一,反而讓人誤以為這是刻意設定。台灣使用者搜尋繁中關鍵字時,你精心翻譯的繁中頁根本沒被當成獨立頁面看待,自然排不上去。

1.3 怎麼第一時間察覺 canonical 指錯

既然肉眼看不出來,就要靠方法主動檢查。最直接的是在任一語言頁按右鍵檢視原始碼,搜尋 canonical 這個字,看它指向的網址是不是這一頁自己。如果繁中頁的 canonical 指向英文首頁,問題就在眼前。第二個訊號在 Search Console:打開涵蓋範圍報告,若大量在地頁被標為「重複,Google 選擇的標準網頁與使用者指定的不同」,幾乎就是 canonical 指錯的典型症狀。第三,觀察各語言版本在自己市場的收錄數,若只有英文版被收錄、其他語言頁幾乎掛零,也是強烈的警訊。這三個檢查點任何一個亮燈,都值得把全站的 canonical 拉出來全面比對。

2. 正確原則:每個語言版本的 canonical 都指向自己

修正的核心觀念只有一句話:每個語言版本的 canonical 應該指向該頁自己,而不是別人。這個原則聽起來簡單,但實際檢查時常常因為模板共用而被忽略,值得逐頁確認。這裡先把修正的優先順序說清楚:先讓每個語言版本的 canonical 自我指涉,地基穩了,再補雙向 hreflang,最後處理 x-default 與跨檔案的 header。順序顛倒常常會讓後面的工作白做,因為 hreflang 指向的網址若跟 canonical 不一致,等於一開始就埋了衝突。

2.1 self-referencing canonical 是多語系的地基

繁中頁的 canonical 就指向繁中頁的網址,日文頁指向日文頁,以此類推。這叫 self-referencing canonical,是多語系網站的地基。地基沒打好,上面疊再多 hreflang 都是空的。我們的做法是先確認每一個語言版本都能自我指涉,再往下做 hreflang,順序不能顛倒。實務上會先用爬蟲工具把全站的 canonical 一次抓出來比對,確認每一頁指向的都是自己的標準網址,而不是首頁或某個集中頁。這一步看似瑣碎,卻是後面所有工作能不能生效的前提。

2.2 只修 canonical 不補 hreflang,效果仍然有限

這裡要澄清一個常見誤會:很多人以為把 canonical 改成指向自己就沒事了。實際上,如果只修 canonical 卻沒補上 hreflang,Google 雖然不再把各語言頁當成重複內容,但它仍然不知道這幾個頁面「彼此是同一份內容的不同語言版本」。少了這層對應關係,Google 可能在錯誤的市場放送錯誤語言的頁面,例如把德文頁推給台灣的使用者。canonical 解決的是「哪個是正版」,hreflang 解決的是「哪個版本給哪個地區的人看」,兩者要一起做才完整。把其中一件當成全部,是我們看過最容易讓人誤判已經修好的環節。

2.3 跨模板稽核才能確認每頁都自我指涉

多語系網站的 canonical 很少是逐頁手寫的,多半由模板或多語系外掛自動生成。這代表問題往往不是單頁錯,而是整類頁面一起錯。我們的稽核做法是把網站按模板分類,例如首頁、產品列表頁、產品單頁、文章頁、聯絡頁各抽一個代表,逐一打開原始碼檢查 canonical 指向。只要某一個模板的 canonical 寫死成首頁,這個模板底下的所有頁面就全部連帶出錯。用爬蟲工具把全站 canonical 一次匯出成表,再對照每頁的實際網址,是最快找出系統性錯誤的方式,比一頁一頁點開可靠得多。

3. hreflang 要寫在 head 裡,而且每條連結都要雙向對應

我們在實務上看過有網站只在 <html lang="zh-tw"> 上標了語言屬性,就以為多語系 SEO 做完了。這其實只做了一小部分,離完整還很遠。

3.1 html lang 屬性不能取代 hreflang

<html lang="zh-tw"> 只是告訴瀏覽器這頁的語言是繁體中文,對輔助工具與使用者體驗有幫助,但對 Google 的多語系 SEO 來說,這個屬性的權重很低。它不能取代 hreflang。真正能讓 Google 建立語言對應關係的,是寫在 <head> 裡、每個語言版本都互相指涉的 <link rel="alternate" hreflang="...">。這兩者常被混為一談,但它們解決的是不同層次的問題,不能互相頂替。

3.2 放 sitemap 不如放 head

hreflang 有三種實作位置:HTTP header、sitemap、以及 HTML 的 head。有些網站把 hreflang 放在 sitemap 裡,這技術上可行,但我們的做法是優先放在每一頁的 head。理由很單純:head 裡的標記跟頁面綁在一起,爬取當下就能被讀到,除錯時打開原始碼就看得見,不用另外去比對 sitemap 有沒有同步。放 sitemap 一旦哪天忘了更新,問題又很難查,維護成本相對高。當然若網站規模很大、頁數成千上萬,sitemap 方式在維護上有它的好處,這時就要看團隊的工具鏈哪一種比較好管理。

3.3 正確的 head 標記長這樣

一個繁中頁,head 裡該同時具備 self-referencing canonical 與完整的 hreflang,實務上會像這樣:

<html lang="zh-TW">
<head>
  <!-- 1. canonical 指向自己 -->
  <link rel="canonical" href="https://www.example.com/zh-tw/" />

  <!-- 2. hreflang 告訴 Google 各語言版本的對應 -->
  <link rel="alternate" hreflang="zh-TW" href="https://www.example.com/zh-tw/" />
  <link rel="alternate" hreflang="ja" href="https://www.example.com/ja/" />
  <link rel="alternate" hreflang="de" href="https://www.example.com/de/" />
  <link rel="alternate" hreflang="en" href="https://www.example.com/en/" />
  <link rel="alternate" hreflang="x-default" href="https://www.example.com/en/" />
</head>

3.4 別漏掉 x-default

上面那組標記裡的 x-default 常被漏掉。它的意思是「如果使用者的語言與地區都不在我列出的清單裡,預設給他看哪一頁」。通常會指向英文版或一個語言選擇頁。少了 x-default,對於不在你目標市場的使用者,Google 只能自己猜要顯示哪個版本,結果不一定理想。舉例來說,一個法國使用者若你沒有法文版,又沒設 x-default,他可能被丟到日文頁,體驗相當差。加上這一行,等於幫所有「名單外」的訪客指定了一個合理的落點。

3.5 非 HTML 檔才需要考慮 HTTP header

三種實作位置裡,HTTP header 這個方式比較少人用,但它有一個無可取代的場景:非 HTML 的檔案。如果你的 PDF 白皮書、規格書也有多語言版本,這些檔案沒有 <head> 可以放 hreflang,這時就得靠伺服器在回應的 HTTP header 裡帶上 Link 欄位來宣告對應關係。一般的網頁內容我們不會特地用這種方式,因為設定與除錯都比 head 麻煩。但如果你的多語系策略涵蓋可下載文件,這是唯一能讓它們也被正確歸類的做法,值得記在清單裡。

4. canonical 與 hreflang 的分工與三個常見錯誤

把兩者的角色與常見錯誤放在一起對照,你會更清楚問題出在哪。

項目 canonical hreflang
要回答的問題 這頁的權威版本是哪個網址 這份內容有哪些語言版本、各給誰看
正確做法 每個語言版本指向自己 列出所有語言版本並互相指涉
建議放置位置 該頁 head 該頁 head(優先於 sitemap)
做錯的後果 在地版本被當重複內容忽略 在錯的市場放送錯的語言
能否單獨使用 可以但不完整 需搭配正確 canonical 才有效

4.1 hreflang 必須雙向對應

hreflang 有一條鐵律:對應關係必須雙向。繁中頁指向日文頁,日文頁也一定要回指繁中頁。只要有一邊漏掉,Google 就會判定這組對應無效而忽略它。我們在實務上看過網站只在首頁做了完整對應,內頁卻各做各的,結果內頁的多語系關係全數失效,這種局部正確反而最難察覺,因為首頁的驗證工具跑起來是綠燈,讓人以為整站都沒問題。建議的檢查方式是逐一模板抽查,確認每個層級的頁面都有回指。

4.2 語言與地區代碼別寫錯

hreflang 的值要用有效的語言代碼,必要時加上地區代碼,例如 zh-TW、en-US。常見的錯誤是把地區代碼當語言代碼用,或用了不存在的代碼。像是想指定台灣卻只寫 tw,但 tw 是地區碼不是語言碼,正確應該是 zh-TW。這些寫錯的標記會被 Google 直接忽略,建議上線前用 hreflang 檢測工具跑一次,把語法錯誤先揪出來。大小寫本身 Google 不計較,但格式與代碼有效性會。

4.3 canonical 與 hreflang 不能互相打架

最後一個雷:canonical 指向的網址,必須跟 hreflang 裡列出的該語言網址完全一致。如果繁中頁 canonical 指向帶斜線的版本,hreflang 卻把繁中版寫成不帶斜線的另一個網址,兩個標籤互相矛盾,Google 收到衝突訊號後,多半兩個都不採信。一致性在這裡不是講究細節,而是能不能生效的前提。我們檢查時會特別核對這兩處的網址字串是否一字不差,包含協定、斜線與參數。

4.4 自動語言重定向會擋住爬蟲

還有一種容易被忽略的干擾,是根據 IP 或瀏覽器語言自動把使用者重定向到某個版本。問題是 Googlebot 多半從美國 IP 爬取,如果你的伺服器偵測到美國 IP 就強制跳轉到英文版,那麼 Googlebot 很可能永遠爬不到你的日文、德文頁,hreflang 做得再完整它也看不到那些頁面。比較穩妥的做法是用 hreflang 讓 Google 自己決定要給使用者看哪個版本,若真的要做自動切換,也要用「建議橫幅」這種不強制跳轉的方式,保留使用者留在原頁與爬蟲抓取的空間。這一點常常是多語系流量莫名其妙起不來的隱藏原因。

5. 多語系最常壞掉的三種情境

除了 canonical 指錯這個大坑,我們診斷過的案例裡還有幾種反覆出現的壞法,放在一起看能幫你少走冤枉路。

5.1 自動翻譯外掛產生的參數網址

有些網站用即時翻譯外掛,語言切換是靠網址後面掛參數完成的,例如同一頁加上 ?lang=ja 就變日文。這種做法的麻煩在於,Google 很可能把帶參數與不帶參數的版本當成同一頁的變體,而不是獨立的語言頁,結果日文內容根本沒機會被當成日文頁收錄。我們的建議是多語系盡量用子目錄或子網域這種有獨立網址的結構,而不是靠參數切換,才能讓每個語言版本有自己明確的網址可以被 canonical 與 hreflang 指認。

5.2 只翻了介面沒翻內容的半套在地化

另一種常見情況是,語言切換後選單、按鈕都變了,主要內文卻還是英文。對 Google 來說,這頁雖然掛著 hreflang="ja",實際內容卻是英文,對應關係的可信度會被打折,日本使用者搜進來看到半英半日的頁面也容易跳出。hreflang 宣告的語言應該跟頁面主體內容真的一致,否則標記做得再完整也無法彌補內容本身的落差。我們的建議是在地化要連正文一起翻,而不是只換一層外殼,否則等於用技術標記去包裝一個其實還沒完成的在地版本。

5.3 新增語言版本後忘了回頭補對應

多語系網站後來新增語言時,很容易只在新頁面加上指向舊頁面的 hreflang,卻忘了回頭在所有舊語言頁補上指向新頁的連結。前面提過 hreflang 必須雙向,少了回指就整組失效。我們的做法是把「新增語言時要更新所有既有頁面的 hreflang 清單」寫進上稿流程的檢查項,避免每加一個語言就埋一組失效對應。

6. 修正之後多久回穩,以及怎麼驗證設對了

修好之後最常被問的,就是流量什麼時候回來、以及怎麼確認真的設對了。這兩件事都有務實的判斷方式。

6.1 影響與回穩都是累積的

canonical 指錯造成的影響是持續累積的,不是某一天突然發生。當各語言版本被判定為重複內容,它們在對應市場的排名會逐漸掉下來,非英語市場受創最深。修正之後也需要 Google 重新爬取與索引才會回穩,通常要數週到數月,頁面愈多、爬取頻率愈低的網站,回穩愈慢。愈早發現愈好,因為累積的傷害會隨時間擴大。

6.2 用三個訊號交叉確認

我們確認有沒有設對的做法是三管齊下:先打開頁面原始碼,確認 head 裡 canonical 指向自己、hreflang 清單完整;再用 hreflang 檢測工具跑一輪,抓語法與雙向對應的錯誤;最後看 Search Console 的國際定位報告有沒有回報衝突。三個訊號都乾淨,才算真的設對。只看其中一個容易漏掉問題,例如工具顯示語法正確,但網址與 canonical 不一致這種邏輯錯誤,往往要回到原始碼才看得出來。修正上線後,可以在 Search Console 對幾個代表性的在地頁提出重新索引要求,加快 Google 重新理解的速度,但不要期待隔天就見效,多語系的重新評估本來就是以週為單位在跑。

7. 常見問題

7.1 canonical 全部指向英文首頁,大概多久會影響流量

影響是持續累積的,不是某一天突然發生。當各語言版本被判定為重複內容,它們在對應市場的排名會逐漸掉下來,非英語市場受創最深。修正之後也需要 Google 重新爬取與索引才會回穩,通常要數週到數月,頁數愈多、爬取頻率愈低的網站回穩愈慢,愈早發現愈好。實務上我們建議修好後把流量按語言分群觀察,單看總量常常因為英文版撐著而看不出在地版本的變化,分開看才能確認每個市場是否真的在回升。

7.2 只把 canonical 改成指向自己,流量就會回來嗎

會改善,但通常不夠。canonical 修正後在地頁不再被當重複內容,這是止血;但要讓 Google 正確地把對的語言送到對的市場,還需要補上雙向的 hreflang。兩件事一起做,恢復的效果才完整。

7.3 hreflang 放在 sitemap 跟放在 head 有差嗎

兩者都被 Google 支援,效果理論上相近。我們偏好放在 head,因為它跟頁面綁在一起,爬取當下就讀得到,除錯時打開原始碼直接看得見。放 sitemap 一旦忘了同步就很難查,維護成本比較高。大型網站則可視團隊工具鏈選擇較好管理的方式。

7.4 x-default 一定要加嗎

強烈建議加。它處理的是那些語言地區都不在你清單內的使用者,替他們指定一個預設版本。沒有 x-default,Google 只能自行判斷要顯示哪個語言頁,結果不見得符合你的預期,也可能把訪客丟到不相干的語言版本。

7.5 只有一種語言的網站需要做 canonical 嗎

需要。就算只有單一語言,self-referencing canonical 仍能幫你收斂同一頁的不同網址變體,例如有無斜線、帶不帶參數的版本,避免同一份內容被拆成多個重複頁分散權重。它是每個網站都該有的基本設定。單語言網站只是不需要處理 hreflang,但 canonical 該做的一樣要做,這點常被誤會成「沒有多語言就不用管 canonical」。

7.6 怎麼確認 canonical 跟 hreflang 都設對了

三管齊下:打開頁面原始碼確認 head 裡的標籤、用 hreflang 檢測工具跑一輪抓語法與雙向對應的錯誤、再看 Search Console 的國際定位報告有沒有回報衝突。三個訊號都乾淨,才算真的設對。另外提醒一點,檢查時不要只驗首頁,要連產品頁、文章頁這些內頁一起抽查,因為很多對應錯誤只發生在內頁,首頁綠燈不代表全站都對。