Featured image of post Next.js 國際化:路由與內容策略Featured image of post Next.js 國際化:路由與內容策略

Next.js 國際化:路由與內容策略

透過 i18n 路由配置、子路徑與網域策略、區域設定偵測、next-intl 整合、多語言網站的 SEO 和 hreflang 掌握 Next.js 國際化。

介紹

國際化是現代 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 文件是用於生產實作的優秀資源。