網站改版紀錄:踩坑與修復中英文切換功能
最近因為想要讓網站的「關於我」、「首頁」與「作品集」能有中英文對照的功能(我需要增加外國的觸及!),所以我嘗試用 AI 幫我寫了一個自動切換語系的按鈕。原本以為只是一個簡單的 JavaScript 按鈕與 CSS 的切換,沒想到卻意外踩了個不小的坑。 這篇快速紀錄一下我遇到的問題,以及後來如何透過改寫 Hugo Shortcode 來優化這個功能。 踩到的坑:全域綁定的災難 一開始,我請 AI 幫我設計一個語言切換功能。它給我的解法看起來很強大: 注入到導航列 (Nav Bar):透過一段全局的 JavaScript,在網頁載入後,強制去尋找網站右上角的選單 #menu,把一個「中/英」切換按鈕塞進去。 全域狀態綁定 (Global State):當你按下按鈕時,會把 lang-en 這個 class 綁定在整個網頁的 <html> 標籤上。 瀏覽器記憶 (Local Storage):甚至還貼心地加了 localStorage 來記住使用者的選擇,讓他們切換到其他頁面時「保持」英文。 聽起來很完美,對吧?但這就是災難的開始: 並非每篇文章都有英文版:我的部落格文章多半只有中文,只有特定幾頁介紹頁面有雙語翻譯。但因為這個按鈕是「全域」的,當讀者在某頁切成英文後,點進其他純中文的文章時,全域 CSS 會嘗試把中文隱藏(因為 <html> 標籤上記住了要看英文),或者是這會導致沒有英文的頁面內容排版錯亂。 畫面閃爍 (Flash of Unstyled Content):由於是用 JS 動態注入按鈕到右上角導航列,這會導致網頁載入完成時,選單才突然跳出一個按鈕。 影響範圍不可控:將行為綁定在最高層級的 HTML 結構與 localStorage 往往會牽連到其他完全不需要多語系的頁面。 解決方法:回歸局部、擁抱 Shortcode 為了一次解決這些問題,我決定拔除所有全域性的語言切換腳本,改成採用「局部(限定頁面)」的作法,主要包含兩個步驟: 1. 限定作用域的 CSS 寫法 捨棄在 <html> 掛載 class,改成針對當前身處頁面的 <body class="page-lang-en"> 進行操作。修改 layouts/partials/extend_head.html 裡面與語言相關的 CSS: <style> /* 預設隱藏英文版 */ .lang-en { display: none; } /* 當特定所在頁面觸發切換時,才隱藏中文,顯示英文 */ body.page-lang-en .lang-en { display: block; } body.page-lang-en .lang-zh { display: none; } </style> 2. 製作專屬的 Hugo Shortcode 我拔掉了會亂篡改全域導航列的 JavaScript,以及會惹麻煩的 localStorage。取而代之的是建立了一個專屬頁面內的 Hugo 短代碼 (Shortcode) layouts/shortcodes/lang-toggle.html: ...