介紹
國際化是現代 Web 應用程式的基本要求。 Next.js 已將其 i18n 支援從 Pages Router 中的整合路由系統發展為 App Router 中靈活的基於中間件的方法。本文涵蓋多語言 Next.js 應用程式的路由策略、區域設定偵測、內容管理和 SEO 最佳化。
關鍵概念是區域設定、預設區域設定、區域設定偵測以及子路徑路由和域路由之間的權衡。 App Router 方法提供了更大的靈活性,但比其前身需要更多的手動設定。
路由策略-子路徑與域
子路徑和網域路由之間的選擇對 SEO 和基礎設施有重大影響。
| 標準 | 子路徑 (/en/about) | 域 (en.example.com) |
|---|---|---|
| SEO權威 | 共享域權限 | 每個語言環境獨立 |
| 地理定位 | 訊號較弱 | 更強的訊號 |
| 基礎架構 | 單一部署 | 多重部署 |
| 分析 | 統一 | 分段 |
對於大多數項目,建議使用子路徑路由,因為它簡單且共享網域權限。 App Router 中的實作使用中間件來處理區域設定前綴重寫。
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
const locales = ["en", "ja", "fr"];
const defaultLocale = "en";
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
const pathnameHasLocale = locales.some(
(locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`
);
if (pathnameHasLocale) return;
const locale = request.cookies.get("NEXT_LOCALE")?.value || defaultLocale;
return NextResponse.redirect(new URL(`/${locale}${pathname}`, request.url));
}
export const config = {
matcher: ["/((?!api|_next|favicon.ico).*)"],
};
區域設定檢測和協商
Next.js 透過協商鏈確定區域設定:cookie 到 Accept-Language 標頭到預設區域設定。 NEXT_LOCALE cookie 約定允許使用者保留其語言首選項。
function getLocale(request: NextRequest): string {
const cookieLocale = request.cookies.get("NEXT_LOCALE")?.value;
if (cookieLocale && locales.includes(cookieLocale)) return cookieLocale;
const acceptLanguage = request.headers.get("accept-language");
if (acceptLanguage) {
const preferred = acceptLanguage
.split(",")
.map((lang) => lang.split(";")[0].trim())
.find((lang) => locales.includes(lang));
if (preferred) return preferred;
}
return defaultLocale;
}
這種協商邏輯可確保使用者始終以自己喜歡的語言查看內容,同時允許手動覆蓋。
使用 next-intl 進行內容管理
next-intl 是 App Router i18n 的推薦函式庫。它提供類型安全的翻譯鍵、命名空間分割和高效的訊息載入。
// middleware.ts
import createMiddleware from "next-intl/middleware";
export default createMiddleware({ locales: ["en", "ja"], defaultLocale: "en" });
export const config = { matcher: ["/((?!api|_next).*)"] };
為了可維護性,翻譯文件按命名空間組織:
{
"navigation": { "home": "Home", "about": "About" },
"home": { "title": "Welcome", "description": "This is the home page" }
}
元件使用 useTranslations 鉤子消耗翻譯:
import { useTranslations } from "next-intl";
function HomePage() {
const t = useTranslations("home");
return <h1>{t("title")}</h1>;
}
多語言網站的 SEO
跨語言 SEO 需要正確的 hreflang 標籤和規範 URL。每個頁面都應包含自引用和備用 hreflang 連結。
export async function generateMetadata({ params }: Props) {
const { locale } = await params;
return {
alternates: {
languages: {
en: "/en/about",
ja: "/ja/about",
"x-default": "/en/about",
},
},
};
}
常見的 SEO 陷阱包括跨區域設置的重複內容、缺少 hreflang 返回連結以及不一致的區域設置 URL 模式。 Google 的指南要求每種語言版本都連結回所有其他語言版本。
結論
對於大多數項目,使用 next-intl 的子路徑路由可提供簡單性、SEO 和開發人員體驗的最佳平衡。投資適當的區域設定檢測中間件,按命名空間組織翻譯文件,並實現完整的 hreflang 元資料。官方 Next.js i18n 範例和 next-intl 文件是用於生產實作的優秀資源。

