Next.js App Router 實(shí)現(xiàn)國際化的核心方法是結(jié)合next-intl 庫進(jìn)行多語言管理,首先在next.config.js 中配置i18n 路由支持,定義locales、defaultLocale 和localeDetection;2. 安裝next-intl 後創(chuàng)建messages 目錄存放各語言JSON 文件,並通過middleware.js 使用withI18nRouting 自動處理語言前綴路由;3. 在app/layout.tsx 中驗(yàn)證locale 並加載對應(yīng)語言消息,使用NextIntlClientProvider 提供翻譯上下文;4. 在組件中通過useTranslations(客戶端)或getTranslations(服務(wù)端)調(diào)用翻譯文本;5. 創(chuàng)建語言切換器組件,利用useRouter 和usePathname 替換路徑前綴實(shí)現(xiàn)語言切換,可配合cookie 持久化用戶偏好;6. 在generateMetadata 中調(diào)用getTranslations 生成多語言SEO 元標(biāo)籤;7. 對於靜態(tài)生成頁面,使用generateStaticParams 為每種語言預(yù)生成路徑;8. 利用next-intl 的useFormatter 和getFormatter 實(shí)現(xiàn)日期、數(shù)字等區(qū)域化格式化;9. 建議按功能模塊拆分翻譯文件以提升維護(hù)性,避免單一文件過大。該方案完整支持SSR、RSC 和Server Actions,是當(dāng)前最穩(wěn)定靈活的Next.js 國際化實(shí)踐。

Next.js 的App Router 從v13 開始引入了對國際化的原生支持,使得多語言網(wǎng)站的開發(fā)更加簡單和結(jié)構(gòu)化。通過內(nèi)置的next-intl
風(fēng)格集成(或使用next-i18next
等第三方庫),你可以輕鬆實(shí)現(xiàn)路由級別的語言切換、翻譯內(nèi)容管理以及區(qū)域化體驗(yàn)。以下是使用App Router 實(shí)現(xiàn)國際化(i18n)的核心方法和最佳實(shí)踐。

? 1. 使用Next.js 內(nèi)置i18n 路由支持
Next.js 原生支持基於路徑前綴的多語言路由(如/en/about
、 /zh/about
),你只需在next.config.js
中配置i18n
字段。
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
i18n: {
locales: ['en', 'zh', 'ja'],
defaultLocale: 'en',
localeDetection: true, // 自動檢測用戶語言},
// 其他配置...
};
export default nextConfig;
-
locales
: 支持的語言列表。 -
defaultLocale
: 默認(rèn)語言。 -
localeDetection
: 是否自動重定向用戶到其首選語言(基於Accept-Language
頭)。
?? 注意:App Router 中雖然支持此配置,但更推薦結(jié)合next-intl
或routing
庫實(shí)現(xiàn)更靈活的控制。

? 2. 使用next-intl
實(shí)現(xiàn)完整的i18n(推薦方式)
next-intl
是目前App Router 下最流行的i18n 解決方案,它與React Server Components 和Server Actions 兼容良好。
步驟一:安裝依賴
npm install next-intl
步驟二:創(chuàng)建語言資源文件
在項(xiàng)目中創(chuàng)建messages
目錄:

/messages
en.json
zh.json
ja.json
示例: en.json
{
"welcome": "Welcome to our app!",
"about.title": "About Us"
}
zh.json
{
"welcome": "歡迎使用我們的應(yīng)用!",
"about.title": "關(guān)於我們"
}
步驟三:配置中間件(Middleware)
創(chuàng)建middleware.js
(或.ts
)來讀取語言並設(shè)置請求上下文:
// middleware.js
import { withI18nRouting } from 'next-intl/middleware';
export default withI18nRouting({
locales: ['en', 'zh', 'ja'],
defaultLocale: 'en',
});
這會自動處理/en/page
、 /zh/page
的路由映射,並支持cookie 或URL 優(yōu)先級判斷語言。
步驟四:在根佈局中加載消息
// app/layout.tsx
import { notFound } from 'next/navigation';
import { NextIntlClientProvider } from 'next-intl';
import { getMessages } from 'next-intl/server';
type Props = {
children: React.ReactNode;
params: { locale: string };
};
export default async function RootLayout({
children,
params: { locale },
}: Props) {
// 驗(yàn)證locale 是否有效const isValidLocale = ['en', 'zh', 'ja'].includes(locale);
if (!isValidLocale) notFound();
// 加載對應(yīng)語言的消息const messages = await getMessages();
return (
<html lang={locale}>
<body>
<NextIntlClientProvider messages={messages}>
{children}
</NextIntlClientProvider>
</body>
</html>
);
}
步驟五:在組件中使用翻譯
'use client';
import { useTranslations } from 'next-intl';
export default function Welcome() {
const t = useTranslations('common');
return <h1>{t('welcome')}</h1>;
}
也可以在Server Component 中使用:
import { getTranslations } from 'next-intl/server';
export default async function About() {
const t = await getTranslations('about');
return <h1>{t('title')}</h1>;
}
? 3. 動態(tài)語言切換(語言選擇器)
創(chuàng)建一個語言切換組件:
'use client';
import { useRouter, usePathname } from 'next/navigation';
import { useLocale } from 'next-intl';
export function LanguageSwitcher() {
const router = useRouter();
const pathname = usePathname();
const locale = useLocale();
const switchTo = (newLocale: string) => {
// 將當(dāng)前路徑從/en/pathname 轉(zhuǎn)為/zh/pathname
router.push(pathname.replace(`/${locale}`, `/${newLocale}`));
};
return (
<div>
<button onClick={() => switchTo('en')}>English</button>
<button onClick={() => switchTo('zh')}>中文</button>
<button onClick={() => switchTo('ja')}>日本語</button>
</div>
);
}
? 提示:你也可以通過cookies().set('NEXT_LOCALE', 'zh')
設(shè)置持久化偏好,在後續(xù)請求中讀取。
? 4. SEO 和元標(biāo)籤的多語言支持
在generateMetadata
中使用翻譯:
// app/about/page.tsx
import { getTranslations } from 'next-intl/server';
export async function generateMetadata({ params }: { params: { locale: string } }) {
const t = await getTranslations({ locale: params.locale, namespace: 'about' });
return {
title: t('meta.title'),
description: t('meta.description'),
};
}
export default function About() {
return <h1>About Page</h1>;
}
? 5. 高級技巧與註意事項(xiàng)
嵌套路由中的i18n :確保每個layout.tsx
都接收params.locale
並傳遞下去。
靜態(tài)生成(SSG)與ISR :配合generateStaticParams
可為每種語言預(yù)生成頁面。
export function generateStaticParams() {
return ['en', 'zh', 'ja'].map((locale) => ({ locale }));
}
日期、數(shù)字格式化: next-intl
提供useFormatter()
和服務(wù)端getFormatter()
,支持區(qū)域化格式。
const format = useFormatter();
format.number(1000); // 根據(jù)locale 顯示千分位
基本上就這些。 Next.js App Router next-intl
的組合目前是實(shí)現(xiàn)i18n 最穩(wěn)定、最靈活的方式,既支持SSR、RSC,又便於維護(hù)多語言內(nèi)容。只要結(jié)構(gòu)清晰,維護(hù)上百個翻譯字段也不復(fù)雜。
? 小建議:把messages
文件按模塊拆分(如common.json
, auth.json
, product.json
),避免單個文件過大。
以上是Next.js應(yīng)用程序路由器中的國際化(I18N)的詳細(xì)內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!