先把結論放在最前面:多語系網站的非英語流量起不來,十之八九不是內容或關鍵字的問題,而是每個語言版本的 canonical 被寫死成指向英文首頁。這一個標籤寫錯,等於主動請 Google 忽略你所有的在地版本。修正的核心只有兩句話,每個語言版本的 canonical 要指向自己,再用雙向的 hreflang 互相指認,兩件事缺一不可。這篇我們用一個真實的慘案,把 canonical 指錯會發生什麼、以及 canonical 與 hreflang 到底怎麼搭配,講到你能直接照做。
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 的國際定位報告有沒有回報衝突。三個訊號都乾淨,才算真的設對。另外提醒一點,檢查時不要只驗首頁,要連產品頁、文章頁這些內頁一起抽查,因為很多對應錯誤只發生在內頁,首頁綠燈不代表全站都對。
