基于语言的路由

在 Next.js (App Router) 中设置基于语言的路由

问题

当一个应用程序支持多种语言时,单一的 URL(例如 /about)本质上是模糊的。访问此 URL 的用户会收到默认语言的内容,但他们无法链接或书签保存该页面的其他语言版本。这种模糊性会让搜索引擎感到困惑,可能不会索引所有语言版本,或者会将它们混淆。

解决方案

将语言标识符直接集成到 URL 路径中,例如 /en/about/fr/about。这使得每个路径都唯一对应于特定语言,从而为用户和搜索引擎解决了模糊性问题。

步骤

1. 创建动态语言段

在 Next.js 的 App Router 中,通过在 app 目录的根目录下创建一个动态段文件夹来处理语言路由。在 app 中创建一个名为 [lang] 的新文件夹,并将主 page.tsx 文件移动到该文件夹中。

// app/[lang]/page.tsx

export default function Home({ params }: { params: { lang: string } }) {
  return (
    <div>
      <h1>主页</h1>
      <p>当前语言:{params.lang}</p>
    </div>
  );
}

这个 [lang] 文件夹捕获 URL 的第一部分(例如 'en' 或 'fr'),并将其作为 params 对象中的 lang 属性传递给页面组件。现在,您可以通过类似 /en/fr 的 URL 访问您的页面。

2. 更新根布局

您的根 layout.tsx 也应移动到 app/[lang] 文件夹中。它同样会接收 lang 参数,您应该使用该参数在 <html> 标签上设置 lang 属性,以提高可访问性和 SEO。

// app/[lang]/layout.tsx

export default function RootLayout({
  children,
  params,
}: {
  children: React.ReactNode;
  params: { lang: string };
}) {
  return (
    <html lang={params.lang}>
      <body>{children}</body>
    </html>
  );
}

此布局现在将特定语言的所有页面包裹起来。在这里设置 lang 属性可以告知浏览器页面内容的语言。

3. 定义支持的语言

要告诉 Next.js 哪些语言段是有效的,您可以从根布局中导出一个 generateStaticParams 函数。这允许 Next.js 在构建时静态生成这些路由。

// app/[lang]/layout.tsx

export async function generateStaticParams() {
  return [{ lang: 'en' }, { lang: 'es' }, { lang: 'fr' }];
}

export default function RootLayout({
  children,
  params,
}: {
  children: React.ReactNode;
  params: { lang: string };
}) {
  return (
    <html lang={params.lang}>
      <body>{children}</body>
    </html>
  );
}

此函数告知 Next.js 您的应用支持 /en/es/fr。对于其他路径(例如 /de)的请求将会返回 404 Not Found 页面。

4. 添加嵌套路由

您应用中的所有其他页面现在都需要在 [lang] 文件夹内创建。例如,要创建一个“关于”页面,您需要添加 app/[lang]/about/page.tsx

// app/[lang]/about/page.tsx

export default function AboutPage({ params }: { params: { lang: string } }) {
  return (
    <div>
      <h1>关于页面</h1>
      <p>当前语言:{params.lang}</p>
    </div>
  );
}

此文件会自动创建可通过 /en/about/es/about/fr/about 访问的路由。如果需要,lang 参数在所有页面上都可用,以便获取正确的翻译内容。