目录

Next.js App Router 国际化实战:使用 next-intl 实现多语言支持

对于使用 Next.js App Router 的项目,next-intl 提供了与框架深度集成、兼容服务端渲染(SSR)、支持 Server/Client 组件的高效国际化方案。本文将逐步讲解如何从 0 到 1 构建一个支持多语言的 Next.js 应用。


🚀 一、为什么选择 next-intl

相比传统的 i18n 库,next-intl 针对 Next.js App Router 做了深度优化:

  • 自动路由处理:自动处理带语言前缀的路由(如 /en/page/zh/page)。
  • 组件支持:完美支持 Server Components 和 Client Components。
  • SEO 友好:原生支持符合 SEO 标准的多语言链接。
  • 按需加载:支持服务器组件中按需加载语言资源,减小首屏体积。

📁 二、项目目录结构

在 App Router 下,推荐的目录结构如下(其中 [locale] 用于动态语言前缀路由):

src/
├── app/
│   ├── layout.tsx                    ← 根布局(非语言相关)
│   ├── middleware.ts                 ← next-intl 中间件
│   ├── i18n/                         ← 国际化配置
│   │   ├── routing.ts
│   │   ├── request.ts
│   │   └── navigation.ts
│   └── [locale]/                     ← 动态语言前缀
│       ├── layout.tsx                ← 语言布局 + Intl Provider
│       ├── page.tsx                  ← 首页
│       └── ...
├── components/
│   └── LocaleSwitcher.tsx            ← 语言切换组件
└── messages/                         ← 翻译资源
    ├── en.json
    └── zh.json

📌 三、核心配置步骤

1. 安装依赖

npm install next-intl

2. 配置语言路由 (src/app/i18n/routing.ts)

import { defineRouting } from "next-intl/routing";

export const routing = defineRouting({
  locales: ["en", "zh"],        // 支持语言
  defaultLocale: "zh",          // 默认语言
  localePrefix: "always"        // 始终使用前缀 /en /zh
});

3. 加载语言资源 (src/app/i18n/request.ts)

import { getRequestConfig } from "next-intl/server";

export default getRequestConfig(async ({ locale }) => {
  return {
    messages: (await import(`../../../messages/${locale}.json`)).default
  };
});

4. 配置中间件 (src/middleware.ts)

import createMiddleware from "next-intl/middleware";
import { routing } from "./app/i18n/routing";

export default createMiddleware(routing);

export const config = {
  // 匹配所有非 API 或 静态资源的路径
  matcher: ["/((?!api|_next|.*\\..*).*)"]
};

🎨 四、页面与组件使用

语言布局配置 (src/app/[locale]/layout.tsx)

import { NextIntlClientProvider } from "next-intl";
import { getMessages } from "next-intl/server";

export default async function LocaleLayout({ children, params: { locale } }) {
  const messages = await getMessages();
  return (
    <html lang={locale}>
      <body>
        <NextIntlClientProvider messages={messages}>
          {children}
        </NextIntlClientProvider>
      </body>
    </html>
  );
}

翻译调用示例

import { useTranslations } from "next-intl";

export default function Home() {
  const t = useTranslations("Index");
  return <h1>{t("title")}</h1>;
}

🎯 五、小结

通过 next-intl,我们可以非常优雅地在 Next.js App Router 中实现多语言支持。它不仅简化了路由逻辑,还提供了出色的开发体验和运行时性能。如果你的项目需要面向国际用户,next-intl 绝对是目前最值得推荐的选择。


📚 推荐阅读