避開 hreflang 的錯誤,首先要把輸入視為一份合約:每一行一個地區標記與一個完整合法的 HTTP 或 HTTPS URL,以單一直立分隔線隔開,並包含當前頁面,同時保留一個 x-default 列作為真實的備援。Hreflang 產生器 透過拒絕相對路徑、片段、嵌入的認證資訊、重複的地區值,以及任何少於兩列的組合來強制執行這份合約,因此格式錯誤的輸入會導致整批失敗,而不是產生一段可被悄悄複製的不完整連結區塊。本地化的決策仍應由人來負責:這個工具會驗證地區標記的格式並統一大小寫(en-us 會變成 en-US,zh-hant 會變成 zh-Hant),但它不會確認你目標的搜尋引擎是否真的支援某個地區,也不會確認每個目的地是否都有翻譯後的內容。將「機器驗證輸入格式」與「人為驗證意圖和內容」這兩個層級視為獨立的檢查關卡,是 hreflang 部署後仍能維持準確的最重要原因。

為什麼輸入錯誤在標籤產生前就會破壞 Hreflang
Hreflang 標籤描述的是已存在 URL 之間的關係,這代表失敗模式通常是輸入錯誤,而非工具錯誤。產生器會解析每一行中一個字面的直立分隔線符號、以瀏覽器等級的解析器來標準化 URL、以 Intl.getCanonicalLocales 來規範化地區標記,並對最終產生的屬性進行 HTML 跳脫。任何無法通過這四個步驟的內容都會被拒絕,整組輸入會被整體放棄而非部分輸出,因為不完整的區塊是正式環境網站最常見的市場遺漏來源。
實際上的意涵是:與其在上線後除錯,投入時間檢查輸入的報酬要高出許多。某一列的 URL 打錯字、另一列缺少通訊協定,或是不慎造成的重複,都不會產出任何連結區塊,迫使團隊在將任何內容複製到內容管理系統之前就必須完成完整的修正。接受部分輸出並將其貼到某一頁而未貼到其對應頁面,正是 Google 的本地化版本指南 所警告的那種漂移,因為搜尋引擎會將單向宣告視為一種訊號,當某頁的替代頁未指向回來時,這個訊號可能會被忽略。
產生器強制執行的列格式規則
每一行必須只包含一個分隔符號和一個 URL,兩者都以純文字撰寫。分隔符號必須是字面的直立分隔線字元;雙重分隔線、Tab 分隔和逗號分隔都會被拒絕。URL 會被標準化為不含片段、不含認證資訊的 HTTP 或 HTTPS 絕對形式,而 & 符號或其他對屬性敏感的字元會在輸出中跳脫為其 HTML 安全形式。最低可行的輸入為兩列(當前頁面加上至少一個替代頁);最高為 100 列,這能讓最終的 head 區塊大小保持在任何內容管理系統範本都能輕鬆處理的範圍內。
| 錯誤 | 錯誤範例 | 結果 |
|---|---|---|
| 相對 URL | /en/page | 拒絕 — 必須提供完整的 http(s) 主機 |
| 通訊協定相對 URL | //example.com/en/ | 拒絕 — 通訊協定必須明確 |
| 含有片段的 URL | https://example.com/en/#intro | 拒絕 — 不接受片段 |
| 含有認證資訊的 URL | https://user:[email protected]/en/ | 拒絕 — 不接受嵌入的認證資訊 |
| 缺少直立分隔線 | en-US https://example.com/en/ | 拒絕 — 每行必須只有一個分隔符號 |
| 重複的地區列 | en-US 列了兩次 | 拒絕 — 標準化後以不區分大小寫方式判定 |
| 只有一列的組合 | 一行 locale|URL | 拒絕 — 至少需要兩列 |
如果想在多個網站批次準備輸入時快速了解這些規則如何互動,Hreflang 產生器的格式與列作弊表 以範本式的範例逐步說明,能與上方的拒絕對照表清楚對應。
地區標記的格式、大寫與 x-default
地區欄位接受兩個字母的語言代碼、可選的四個字母文字代碼,以及可選的兩個字母地區代碼,依此順序。國家代碼不能單獨出現在第一個位置;第一個子標籤代表語言,因此 fr-CA 有效,而 CA-fr 則會被拒絕。文字子標籤可用來區分書寫系統,例如 zh-Hans 與 zh-Hant,這對同時服務簡體中文和繁體中文使用者的網站來說是不可或缺的。不含地區的通用語言代碼(單獨的 fr 或單獨的 en)在你要為同一語言推出多個國家專屬版本時,作為備援仍然非常實用。
| 輸入 | 標準輸出 | 用途 |
|---|---|---|
| en-us | en-US | 地區性英文 — 統一地區大小寫 |
| zh-hant | zh-Hant | 繁體中文文字,文字大小寫標準化 |
| fr-CA | fr-CA | 已為加拿大法文的標準形式 |
| fr | fr | 適用於多地區的通用法文備援 |
| de-AT | de-AT | 奧地利德文 — 先語言後地區的順序 |
| x-default | x-default | 特殊備援代記號,非語言 |
x-default 代記號並不代表任何語言。它代表的是一個要給設定不符合其他列出之替代頁的使用者查看的頁面,通常是國家選擇器或通用的到達頁。一組中只能出現一個 x-default 列,而且它的加入必須反映一個真實存在的備援,而非為了通過驗證而設計的佔位列。地點標記會在解析後以標準大小寫形式輸出,這就是為什麼 en-us 與 zh-hant 在輸出中會變成 en-US 與 zh-Hant;這種一致性很重要,因為搜尋引擎在將標記與受眾配對時,會把大小寫視為有意義的資訊。
逐步產生乾淨的 Hreflang 標籤
- 盤點所有等價的本地化頁面。列出每一個作為翻譯或地區變體存在的 URL,包含目前正在編輯的頁面。如果某個 URL 對其目標受眾沒有提供有用的內容,請先修正內容;hreflang 無法拯救內容單薄或空白的翻譯。
- 以 locale|URL 格式為每個頁面寫一行。使用標準的兩個字母語言代碼加上可選的四個字母文字代碼,再加上可選的兩個字母地區代碼。在地區與 URL 之間只放一個字面的直立分隔線,不要有額外的分隔符號、註解或結尾空白。
- 確認每個 URL 都是完整合法的。包含通訊協定與主機 — 使用 https://example.com/en/ 而非 /en/ — 並移除任何片段或嵌入的認證資訊。瀏覽器的 URL 解析器會拒絕任何不是絕對 HTTP(S) 的內容。
- 只有在備援真實存在時才加入 x-default。為國家選擇器、無地區的到達頁或真正通用的內容保留一列。絕不要重複 x-default,也絕不要把它當作缺少地區時的代用品。
- 產生連結區塊並檢視跳脫後的輸出。將列清單貼入 Hreflang 產生器,確認每個地區都已按預期標準化(en-us → en-US),然後原封不動地複製產生的 <link rel="alternate" …> 元素。& 符號與引號在輸出中會以 HTML 跳脫形式呈現。
- 在每個替代頁面的 head 中安裝完全相同的區塊。完全相同的一組內容必須出現在每個本地化版本的 head 中,包含正在編輯之頁面的自我參照。自我參照與回指標籤被記錄為必要訊號,理由與單向宣告可能被忽略相同:其他網站不應該能夠單方面宣稱你的頁面是它的替代頁。
- 對每個語言群組進行抽樣檢查。驗證每個 URL 都回傳 200 回應,head 中包含完整的一組內容,且該列上的地區與所抓取的頁面相符。將任何 3xx 重新導向、404 或缺少的連結元素視為產生錯誤,而非工具限制。
安裝相同的組合並確認對等連結
部署後的漂移是輸入錯誤之後,hreflang 問題的第二大來源。一旦連結區塊產生完畢,就必須原封不動地放進群組中每個頁面的 head,而 WHATWG 規格明確指出 替代連結描述的是等價資源之間的關係,而非一個頁面會轉址到另一頁的暗示。如果頁面 A 列出了 B、C 和 D,但頁面 B 只列出 A 和 D,即使每個標籤在語法上都正確,這個實作仍然是壞的。
選擇一種實作方式 — HTML head 元素、HTTP Link 標頭,或 XML sitemap 項目 — 並一致地維護它。搜尋引擎將這三種視為等價,但同時維護多份副本會產生漂移,因為內容團隊更新了其中一個來源而沒有更新另一個。產生器專門產生 HTML head 元素;如果你的發佈系統更適合使用 HTTP 標頭,請把產生的區塊視為單一事實來源,再謄寫到對應的標頭格式中。避免在同一個群組中混用來源,因為即使其他每個頁面都完美,一個不一致的頁面就足以讓群組中其餘頁面的訊號失效。
部署之後:檢查、比對與更新紀律
零錯誤的 hreflang 產生之後,還需要零錯誤的維護。產生器無法連到遠端頁面,也無法證明整個上線網站之間的對等連結,因此持續的品質有賴於定期的檢查。在每個發佈週期至少從每個群組抓取一次最新的 head,將連結區塊與儲存的基準進行比對,並調查任何已無法解析到其所宣告之地區的列。移除了地區、重新導向的 URL,或移動過的標準網址,都需要重新產生受影響的整組內容,而不是逐列修補,因為同一個區塊仍必須同時安裝到每個替代頁的 head 中。
當新增地區時,請重新產生整個群組,而非只延伸某一頁,並確認新項目隨每個既有替代頁的 URL 一起出貨。當移除某個市場時,在同一次變更中將它從每個存活頁面的組合中一併剪除,讓標籤不會比它所描述的頁面活得更久。當 URL 變更時,重新產生一次並重新部署到所有地方,因為標籤區塊中寫死的重新導向本身就是一種常見錯誤,常常在重新導向本身被移除之後仍悄悄存在。本地化架構要保持準確,只有在輸入經過審查、區塊在每個替代頁之間完全一致,並且部署差異是與前一版相同組合進行比對而非與不相關的基準進行比對時才能成立。