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 文档是用于生产实现的优秀资源。