
前言
在開發網站時,多國語系功能(i18n)是很常見的需求,能根據使用者需求切換網站顯示的語言。這陣子在 Next.js 專案中意外踩了幾個坑,寫下學習筆記作為紀錄。
本篇分為以下幾個段落:
- What is i18n?
- 如何實作
- Next.js 內建:路由層級
- 選擇套件:react-i18next & next-i18next
- 使用範例
- SSG/SSR:使用 next-i18next
- SPA:使用 react-i18next
What is i18n?
i18n 是由 internationalization(國際化)英文縮寫而來,18 代表 i 到 n 之間的字母數量。
透過 i18n 多國語系功能,能夠讓不同語系的使用者,根據需求選定顯示語言和格式,減少在地化的時間成本,達到國際化的目的。
如何實作
Next.js 內建:路由層級
在介紹套件之前,先介紹 Next.js 官方內建 i18n 功能,透過路由層級(routing)設定不同語言轉至不同路徑,設定範例如下:
1 | // next.config.js |
根據上述配置,即可搭配 next/link、next/router,根據路由顯示對應的語言,路徑如下:
/posts:預設為en/zh/blog/jp/blog
其中需注意 Page Router 和 App Router 在路由設定上有所不同,詳細可參考官方提供的範例,以下介紹常見的 i18n 套件作為範例。
關於 Page router 和 App router 的差別,可參考之前的筆記:【學習筆記】Next.js 路由系統:App Router vs Page Router
選擇套件:react-i18next & next-i18next
- i18next/next-i18next
- 支援 Page Router
- 支援 SSG/SSR
- i18next/react-i18next
- 支援 APP Router,因此 Next.js v13 後的版本建議搭配使用
- 支援 SPA
可參考上述兩種套件的 npm 下載數:

使用範例
SSR:使用 next-i18next
(1) 首先是安裝套件:
1 | npm install next-i18next --save |
(2) 在根目錄新增 next-i18next.config.js 設定檔:
1 | // next-i18next.config.js |
(3) 在 next.config.js 設定檔引入使用 next-i18next:
1 | // next.config.js |
(4) 修改 src/pages/_app.tsx 檔案,以 appWithTranslation 這個 HOC(高階組件)包住整個 App:
1 | // src/pages/_app.tsx |
【補充】Higher-Order Components(HOC,高階組件)
- HOC 並不是 React 提供的 API,而是和 JavsScript 中的 Higher Order Function(高階函式)類似的一個函式,高階函式可代入另一個函式作為參數,最終回傳一個函式作為結果
- 而 HOC 則是可代入元件(Component)作為參數,並回傳一個新的元件
- 目的是將共用邏輯放在 HOC 中,變動的部分由 Component 的 props 和 state 傳入
(5) 在 public/locales/<locale>/<namespace>.json 路徑加入多國語系檔案,架構參考如下:
1 | . |
(6) 在頁面引入語系檔案:
1 | import { serverSideTranslations } from 'next-i18next/serverSideTranslations' |
(7) 即可在頁面引入 useTranslation hook 使用,注意需從 next-i18next 引用:
1 | import { useTranslation } from 'next-i18next' |
SPA:使用 react-i18next
非 SSR、SSG 環境,只需直接引用 react-i18next 套件即可。
(1) 首先是安裝套件:
1 | npm install react-i18next i18next --save |
(2) 建立 app/i18n 目錄,放置管理 i18n 的相關檔案(初始 i18n、翻譯文檔),範例如下:
i18n/index.ts:初始 i18n 相關設定
1 | // i18n/index.ts |
i18n/lang-resource:定義語系與對應文字的 json 檔
1 | // i18n/lang-resource |
(3) 設定完成後,即可在 app/pages/layout 引入 i18n/index.ts 使用:
1 | // app/pages/layout |
以 app/pages/login/page.tsx 為例:
1 | // app/pages/login/page.tsx |
(4) 若要切換語系,可使用 i18n.changeLanguage 方法:
1 | // app/component/header.tsx |
結論
其實一開始研究實作 i18n 功能時,看到官方文件整個頭昏眼花,Next.js 內建的路由實作上又稍嫌複雜,React 生態不像 Angular 框架能直接引入內建功能實作,反而有很多種套件能夠選擇使用。
但問題來了,套件引入使用下來卻噴一堆 Error,才發現到由於 Next.js 路由系統架構,需搭配支援 App Router 或 Page Router 的套件使用,其實想成是在實作 React 多國語系功能就單純許多;雖然文中提及的 Page Router 還沒有機會實作,概念上還有點模糊,但還是先寫下筆記留作紀錄。
參考資料
- 一篇文章了解如何在 Next.js 中集成 i18n 国际化(含踩坑及开发配置)
- 【Next】i18n使用 - JohnShu Blog
- 【DAY20】React Native - 多語系切換 (react-i18next)
- 使用 next-i18next 實作中英文多語系 - Modern Next.js Blog 系列 #28