如果你在 Astro 文件的 repository 提交有關翻譯的 pull request,偶爾會遇到 CI 在這邊發生錯誤:CI / Check Links (pull_request),點進去看錯誤訊息通常是:
Error: Broken fragment link in src/content/docs/zh-tw/<...>.mdx, line <...>: The linked page does not contain a fragment with the name "#<some-anchor>". Available fragments: ...在這篇文章我要探討這個錯誤的成因以及解決方法。
我先解釋這個錯誤的意思:你要提交的 MDX 檔案中有連結裡面有不存在的錨點(anchor)ID。
此時有人可能會想「我已經照英文版翻譯,把連結從 /en/ 開頭改成 /zh-tw/ 開頭,怎麽會出現不存在的錨點 ID 呢?」或者是「我根本沒有動到這個檔案,為什麼是這個檔案出現這個錯誤呢?」
這是因為錨點 ID 會隨著翻譯改變。Astro 文件網站內部的 Astro 在處理 Markdown/MDX 檔案時,會為標題加上一個 id,這個 id 是將標題文字經過 github-slugger 產生的 slug。文件頁面內的標題也是要翻譯的,經過翻譯的標題產生的 slug 自然跟原文標題的不一樣。
這樣的解釋似乎還是沒辦法解答剛剛提出的問題,所以我舉一個例子:文件裡面有兩個頁面 A 和 B,A 裡面包含連往 B 某個標題的連結 /en/B#untranslated-heading。
在 A 先被翻譯的情況下,因為 B 還沒翻譯,所以對這個連結我們只改語系: /zh-tw/B#untranslated-heading 。在之後翻譯 B 的時候,pull request 如果沒有改 A 頁面的連結,因為翻譯的頁面已經沒有這個錨點了,所以會報這個錯誤。我們要修改 A 頁面的這個連結成 /zh-tw/B#已翻譯標題 才不會報錯。
在 B 先被翻譯的情況下,這個標題已經被翻譯成 已翻譯標題。在之後翻譯 A 的時候,如果只改語系、留著連結錨點沒翻譯的話,在送 pull request 一樣會出現這個錯誤,所以要連錨點一起翻譯成 /zh-tw/B#已翻譯標題 才不會報錯。
我這個例子大概可以解釋為什麼會發生這兩種有點奇怪的狀況了。但是我要怎麽判斷哪些連結的錨點 ID 要改,哪些不用呢?
最簡單的方法是先發 pull request,有錯再改。
如果不想依靠 CI 檢查的話,就只能手動檢查了。對這種文件的內部連結,我們可以分成連入這個頁面跟連出這個頁面的連結。對連出的連結,只要在頁面中檢查連結的頁面在 Astro 文件網站有沒有翻譯,有就改成對應的錨點,沒有就只改語系。連入的連結就比較麻煩了,要先在 repository 搜尋連入這個頁面的連結,然後一個個改錨點。至於錨點要改成什麼呢?照 github-slugger 的規則找出 ID?填入跑 github-slugger 後的結果?反正有很多找出錨點 ID 的方法。