在上一篇文章中,我們學會了如何用按鈕手動切換語言。但在實際應用中,為了 SEO 以及方便使用者分享特定語言的頁面,我們通常會希望語言狀態能反映在 URL 上(像是:example.com/zh/home)。
react-router-dom 與 i18next,讓網址自動與語言同步。如果你還沒看過第一篇,建議先閱讀! 【React i18n 實戰 1】專案中實現多語系功能
為何網址需要帶語言程式碼?
在網址戴上語言別基本上有兩種好處:
- SEO 友善:搜尋引擎可以分別索引不同語言的頁面。
- 狀態保留:當使用者重新整理網頁或把連結傳給朋友時,語言設定不會跑掉。
實作步驟
1. 設定路由結構
首先,我們要在路由設定中加入動態參數 :lang ,這個參數用來代表要使用的語言。
// App.jsx
import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom";
function App() {
return (
<BrowserRouter>
<Routes>
{/* 動態捕捉語言參數,如 /en/home 或 /zh/about */}
<Route path="/:lang/*" element={<MainLayout />} />
{/* 如果沒有帶語系,則導向預設語系 */}
<Route path="*" element={<Navigate to="/en" replace />} />
</Routes>
</BrowserRouter>
);
}
2. 同步 URL 與 i18n 狀態
當使用者手動修改網址時(例如把 /en 改成 /zh), i18n 必須立刻切到換對應語言的文字。
我們可以在 layout 組件(如 MainLayout.jsx)中使用 useEffect 來監控:
import { useEffect } from "react";
import { useParams } from "react-router-dom";
import { useTranslation } from "react-i18next";
function MainLayout() {
// 取得動態參數值
const { lang } = useParams();
const { i18n } = useTranslation();
useEffect(() => {
// 當 URL 的 lang 改變,且不等於目前的語言時,強制切換 i18n 狀態
if (lang && i18n.language !== lang) {
i18n.changeLanguage(lang);
}
}, [lang, i18n]);
return (
<div>
<Header />
{/* 頁面內容 */}
</div>
);
}
3. 語系切換器的調整
現在切換語言不再只是單純的呼叫 changeLanguage,而是連動「跳轉網址」。
程式運作的順序為:
- 用 select 切換語言
- 將 URL 中的動態參數換成 select 選中的語言
- 重新導向到新的網址
import { useNavigate, useLocation } from "react-router-dom";
function LanguageSwitcher() {
const navigate = useNavigate();
//取得當前 URL 狀態
const location = useLocation();
const handleLanguageChange = (newLang) => {
// 取得當前路徑並替換掉語言部分
const pathNodes = location.pathname.split("/");
pathNodes[1] = newLang; // 替換掉 lang 參數位置
navigate(pathNodes.join("/"));
};
return (
<select onChange={(e) => handleLanguageChange(e.target.value)}>
<option value="en">English</option>
<option value="zh">繁體中文</option>
</select>
);
}
總結
透過這幾步,我們成功讓 URL 成為語言狀態的「單一真相來源 」。除了對使用者體驗加分外,也有助於提升網站的 SEO !!
目前為止,基本上已經是一個完整的切換語言功能了,但還有個可以優化的部分,那就是我們的翻譯資源還是手動 import 進來的。當網站功能越來越多、翻譯檔越來越胖,可能會影響網站載入速度,下一篇,我會分享如何使用 i18next-http-backend 實現 「動態載入 (Lazy Loading)」。

















