关于 next-intl-app-router
next-intl-app-router 是面向 Next.js App Router 项目的 next-intl 配置与使用指南,采用前缀式语言路由。内容涵盖配置、语言感知导航、静态渲染和翻译加载,并提供可复制的示例。
主要功能
- 01前缀式语言路由
- 02插件与请求配置
- 03语言感知导航辅助项
- 04静态渲染设置
- 05客户端与服务端翻译 API
- 06按语言划分的 JSON 消息文件
适用场景
- 01为 Next.js 应用添加带语言前缀的 URL
- 02在 App Router 中配置 next-intl
- 03构建语言感知链接与重定向
- 04在客户端和服务端组件中加载翻译
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ liuchiawei/ agent-skills --skill next-intl-app-router安装后在 Claude Code 中输入/next-intl-app-router确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
reference.mdexamples/app-locale-about-page.tsxapp-locale-layout.tsxapp-locale-page.tsxBackToHomeButton.tsxmessages-en.jsonNav-client.tsxnext.config.tsproxy.tsREADME.mdexamples/i18n/navigation.tsrequest.tsrouting.ts详细介绍
next-intl(App Router)
介绍如何在 Next.js App Router 项目中使用 next-intl 实现基于前缀的区域设置路由(例如 /en/about、/ja/about)。适用于任何 Next.js App Router 项目。
示例代码: 可直接复制粘贴的示例位于此技能的 examples/ 文件夹中。请参阅 examples/README.md,了解每个文件在项目中的存放位置。
文件布局
保持此结构:
├── messages/
│ ├── en.json
│ ├── ja.json
│ └── ...
├── next.config.ts
└── src/
├── i18n/
│ ├── request.ts
│ ├── routing.ts
│ └── navigation.ts
├── proxy.ts # Next.js 16+ (was middleware.ts)
└── app/
├── layout.tsx # Root layout, no NextIntlClientProvider here
└── [locale]/
├── layout.tsx
├── page.tsx
└── ...
根布局不会使用 NextIntlClientProvider 包裹内容;只有 app/[locale]/layout.tsx 会这样做。
1. Next 配置
接入插件(默认路径为 ./i18n/request.ts):
// next.config.ts
import type { NextConfig } from "next";
import createNextIntlPlugin from "next-intl/plugin";
const nextConfig: NextConfig = {
/* ... */
};
const withNextIntl = createNextIntlPlugin();
export default withNextIntl(nextConfig);
自定义路径:createNextIntlPlugin('./src/i18n/request.ts')。
2. 路由配置
在 src/i18n/routing.ts 中集中配置:
import { defineRouting } from "next-intl/routing";
export const routing = defineRouting({
locales: ["en", "ja", "zh-CN", "zh-TW"],
defaultLocale: "en",
});
3. 请求配置
src/i18n/request.ts:从 [locale] 路径段解析区域设置并加载消息。
import { getRequestConfig } from "next-intl/server";
import { hasLocale } from "next-intl";
import { routing } from "./routing";
export default getRequestConfig(async ({ requestLocale }) => {
const requested = await requestLocale;
const locale = hasLocale(routing.locales, requested)
? requested
: routing.defaultLocale;
return {
locale,
messages: (await import(`../../messages/${locale}.json`)).default,
};
});
4. Proxy / 中间件(Next.js 16)
Next.js 16 使用 proxy.ts,而不是 middleware.ts。API 相同:
// src/proxy.ts
import createMiddleware from "next-intl/middleware";
import { routing } from "./i18n/routing";
export const proxy = createMiddleware(routing);
export const config = {
matcher: "/((?!api|trpc|_next|_vercel|.*\\..*).*)",
};
匹配器:匹配所有路径名,但排除 /api、/trpc、/_next、/_vercel 以及包含句点的路径(例如 favicon.ico)。
5. 导航辅助工具
使用项目的导航封装,让链接保留当前区域设置:
// src/i18n/navigation.ts
import { createNavigation } from "next-intl/navigation";
import { routing } from "./routing";
export const { Link, redirect, usePathname, useRouter, getPathname } =
createNavigation(routing);
在组件中:请从 @/i18n/navigation 导入 Link(及其他辅助工具),以生成适配区域设置的 URL;不要从 next/navigation 或 next/link 导入。示例:examples/Nav-client.tsx、examples/BackToHomeButton.tsx。
6. 区域设置布局与静态渲染
app/[locale]/layout.tsx 必须(完整文件:examples/app-locale-layout.tsx):
- 使用
hasLocale验证locale→ 如果无效,则调用notFound()。 - 调用
setRequestLocale(locale)以进行静态渲染。 - 使用
NextIntlClientProvider和getMessages()包裹子内容。
// app/[locale]/layout.tsx
import { NextIntlClientProvider, hasLocale } from "next-intl";
import { setRequestLocale } from "next-intl/server";
import { notFound } from "next/navigation";
import { routing } from "@/i18n/routing";
import { getMessages } from "next-intl/server";
type Props = {
children: React.ReactNode;
params: Promise<{ locale: string }>;
};
export function generateStaticParams() {
return routing.locales.map((locale) => ({ locale }));
}
export default async function LocaleLayout({ children, params }: Props) {
const { locale } = await params;
if (!hasLocale(routing.locales, locale)) notFound();
setRequestLocale(locale);
const messages = await getMessages();
return (
<NextIntlClientProvider messages={messages}>
{children}
</NextIntlClientProvider>
);
}
7. [locale] 下的页面
要进行静态渲染,[locale] 下每个使用 next-intl 的页面都必须调用 setRequestLocale(locale)(并在需要时使用 use(params))。示例:app-locale-page.tsx、app-locale-about-page.tsx。(并在需要时使用 use(params)。)布局已设置该值;使用区域设置渲染服务器组件的页面也应设置该值。
// app/[locale]/page.tsx
import { use } from "react";
import { setRequestLocale } from "next-intl/server";
export default function IndexPage({
params,
}: {
params: Promise<{ locale: string }>;
}) {
const { locale } = use(params);
setRequestLocale(locale);
return <TokyoPage />;
}
// app/[locale]/about/page.tsx
import { use } from "react";
import { setRequestLocale } from "next-intl/server";
import AboutContainer from "./components/AboutContainer";
export default function AboutPage({
params,
}: {
params: Promise<{ locale: string }>;
}) {
const { locale } = use(params);
setRequestLocale(locale);
return <AboutContainer />;
}
在该布局或页面中调用任何 next-intl API 之前,先调用 setRequestLocale。
8. 使用翻译
客户端组件: useTranslations(namespace):
"use client";
import { useTranslations } from "next-intl";
import { Link } from "@/i18n/navigation";
export default function BackToHomeButton() {
const t = useTranslations("BackToHomeButton");
return (
<Link href="/">
<span>{t("buttonText")}</span>
</Link>
);
}
"use client";
import { useTranslations } from "next-intl";
import { Link } from "@/i18n/navigation";
export default function Nav() {
const t = useTranslations("Navigation");
return <Link href="/about">{t("links.about")}</Link>;
}
服务器组件: 使用 next-intl/server 中的 getTranslations(根据需要传入区域设置或命名空间,并使用 await)。
9. 消息格式
在 messages/ 下为每种区域设置创建一个 JSON 文件。嵌套键对应命名空间和键:
{
"HomePage": {
"title": "Hello world!"
},
"LandingPage": {
"title": "Tokyo Sounds",
"navbar": {
"home": "Home",
"about": "About"
}
},
"BackToHomeButton": {
"buttonText": "Back to Home",
"tooltip": "Return to the main page"
}
}
useTranslations("LandingPage")→t("title")、t("navbar.about")。- 插值:
"selectColor": "Select {color} color"→t("selectColor", { color: "Blue" })。
检查清单
-
next.config.ts:使用createNextIntlPlugin()包装配置。 -
src/i18n/routing.ts:使用defineRouting配置locales和defaultLocale。 -
src/i18n/request.ts:使用getRequestConfig+hasLocale+ 动态加载messages/${locale}.json。 -
src/proxy.ts(或middleware.ts):使用createMiddleware(routing)和匹配器。 -
src/i18n/navigation.ts:使用createNavigation(routing)并重新导出Link等。 -
app/[locale]/layout.tsx:使用hasLocale→notFound、setRequestLocale、generateStaticParams、NextIntlClientProvider+getMessages()。 - 每个
app/[locale]/**/page.tsx:使用静态渲染时调用setRequestLocale(locale)。 - 客户端组件:使用
useTranslations("Namespace");链接使用从@/i18n/navigation导入的Link。
参考
- 可直接复制粘贴的示例: examples/ — 可在任何项目中使用的独立文件。
- 扩展配置(localePrefix、pathnames 等):reference.md
- 官方文档:next-intl App Router、Routing setup