Next.js App Router 國際化 i18n 多語系完整教學:打造多國語言網站
為什麼你的網站需要國際化?
如果你正在經營一個面向全球使用者的網站,或者你的產品有多國市場的需求,國際化(i18n)就是你必須面對的課題。i18n 不只是把文字翻譯成不同語言這麼簡單,它還涉及日期格式、數字格式、文字方向(RTL/LTR),以及最重要的——SEO。
我之前幫一個電商客戶做多語系網站,上線後日文版的自然流量在三個月內成長了 200%。原因很簡單:Google 會根據 hreflang 標籤把正確的語系版本推送給對應地區的使用者。如果你還在用一個語言打天下,你可能正在錯過大量的潛在流量。
Next.js App Router 的 i18n 策略
在 Next.js 13+ 的 App Router 中,官方推薦使用「子路徑」方式來處理多語系,也就是 URL 會長這樣:
/zh-TW/about— 繁體中文版/en/about— 英文版/ja/about— 日文版
這種方式對 SEO 最友善,因為每個語系都有獨立的 URL,搜尋引擎可以分別索引。相比之下,用 cookie 或 header 來切換語系的方式,Google 是看不到不同語言版本的。
如果你還不熟悉 App Router 的基本架構,建議先看看 Next.js App Router 遷移指南。
專案架構設定
首先安裝 next-intl,這是目前 Next.js App Router 最推薦的 i18n 套件:
npm install next-intl
接著調整你的專案目錄結構:
app/
[locale]/
layout.tsx
page.tsx
about/
page.tsx
messages/
zh-TW.json
en.json
ja.json
middleware.ts
i18n.ts
關鍵在於那個 [locale] 動態路由資料夾。所有頁面都放在這個資料夾底下,Next.js 會自動把 URL 中的語系參數傳進來。
建立 i18n.ts 設定檔:
import {getRequestConfig} from 'next-intl/server';
export const locales = ['zh-TW', 'en', 'ja'] as const;
export const defaultLocale = 'zh-TW';
export default getRequestConfig(async ({locale}) => ({
messages: (await import(`./messages/${locale}.json`)).default
}));
Middleware 語系偵測與重導
Middleware 負責兩件事:偵測使用者的語系偏好,以及把沒有語系前綴的 URL 重導到對應的語系路徑。
import createMiddleware from 'next-intl/middleware';
import {locales, defaultLocale} from './i18n';
export default createMiddleware({
locales,
defaultLocale,
localeDetection: true,
localePrefix: 'as-needed'
});
export const config = {
matcher: ['/((?!api|_next|.*\..*).*)']
};
localePrefix: 'as-needed' 的意思是預設語系(zh-TW)不需要在 URL 中顯示前綴,其他語系才需要。這樣你的中文使用者看到的 URL 會是乾淨的 /about 而不是 /zh-TW/about。
如果你對 Next.js Middleware 的運作機制還不太熟,建議先了解一下,因為 i18n middleware 是在 Edge Runtime 上執行的。
翻譯檔案管理
翻譯檔案就是一般的 JSON 檔,用巢狀結構組織:
// messages/zh-TW.json
{
"common": {
"title": "下班黑客學",
"nav": {
"home": "首頁",
"about": "關於我們",
"blog": "部落格"
}
},
"home": {
"hero": "用下班時間,學會改變人生的技術",
"cta": "開始學習"
}
}
幾個管理翻譯檔案的建議:
- 按頁面或功能分組:用
common、home、about等 namespace 來組織 - key 用英文命名:方便所有開發者理解,不管他們懂不懂目標語言
- 保持各語系檔案結構一致:如果 zh-TW.json 有某個 key,其他語系檔也必須有
- 考慮用 Crowdin 或 Phrase 管理:當翻譯量大到一定程度,手動管理 JSON 會很痛苦
在元件中使用翻譯
在 Server Component 和 Client Component 中使用翻譯的方式略有不同:
Server Component
import {useTranslations} from 'next-intl';
export default function HomePage() {
const t = useTranslations('home');
return (
<div>
<h1>{t('hero')}</h1>
<button>{t('cta')}</button>
</div>
);
}
Client Component
'use client';
import {useTranslations} from 'next-intl';
export default function SearchBar() {
const t = useTranslations('common');
return <input placeholder={t('searchPlaceholder')} />;
}
next-intl 的好處是 Server 和 Client Component 用一樣的 API,不需要學兩套不同的用法。
SEO 最佳化:hreflang 與 metadata
這是 i18n 中最容易被忽略但最重要的一環。你需要在每個頁面的 <head> 中加入 hreflang 標籤,告訴搜尋引擎這個頁面有哪些語系版本:
// app/[locale]/layout.tsx
import {locales} from '@/i18n';
export function generateMetadata({params: {locale}}) {
return {
alternates: {
canonical: `https://yourdomain.com/${locale}`,
languages: Object.fromEntries(
locales.map(l => [l, `https://yourdomain.com/${l}`])
),
},
};
}
另外,記得在 sitemap.xml 中也要包含所有語系版本的 URL,這樣搜尋引擎才能完整索引你的多語系內容。如果你對 Next.js Server Actions 熟悉的話,你也可以用 Server Action 來動態產生 sitemap。
語系切換元件實作
最後來實作語系切換的下拉選單:
'use client';
import {useLocale} from 'next-intl';
import {useRouter, usePathname} from 'next-intl/client';
const localeNames = {
'zh-TW': '繁體中文',
'en': 'English',
'ja': '日本語',
};
export default function LanguageSwitcher() {
const locale = useLocale();
const router = useRouter();
const pathname = usePathname();
const handleChange = (e) => {
router.replace(pathname, {locale: e.target.value});
};
return (
<select value={locale} onChange={handleChange}>
{Object.entries(localeNames).map(([code, name]) => (
<option key={code} value={code}>{name}</option>
))}
</select>
);
}
這個元件會在使用者切換語系時,保持在同一個頁面但切換到對應的語系版本。URL 會自動更新,而且不會整頁重新載入。
總結與下一步
用 Next.js App Router 搭配 next-intl 來做國際化,整個流程其實蠻順暢的。重點整理一下:
- 用
[locale]動態路由來組織多語系頁面 - Middleware 處理語系偵測和重導
- JSON 檔案管理翻譯內容
- hreflang 標籤對 SEO 至關重要
- 語系切換元件讓使用者自由選擇語言
下一步,你可以考慮加入更進階的功能,像是根據使用者地理位置自動切換語系、支援 RTL 排版(如阿拉伯文),或是整合翻譯管理平台來簡化翻譯流程。國際化做得好,你的網站就能觸及全球的使用者。
繼續閱讀
Next.js Turbopack 完整教學:Rust 驅動的打包工具設定與效能優化指南
相關文章
你可能也喜歡
探索其他領域的精選好文