使用您最喜欢的AI助手总结文档,并引用此页面和AI提供商
通过将 Intlayer MCP 服务器集成到您的 AI 助手,您可以直接从 ChatGPT、DeepSeek、Cursor、VSCode 等获取所有文档。
查看 MCP 服务器文档此页面的内容已使用 AI 翻译。
查看英文原文的最新版本如果您有改善此文档的想法,请随时通过在GitHub上提交拉取请求来贡献。
文档的 GitHub 链接复制文档 Markdown 到剪贴板
Next.js 国际化 (i18n) 与 next-intl 和 Intlayer
next-intl 和 Intlayer 是为 Next.js 应用程序设计的开源国际化 (i18n) 框架。它们广泛用于管理软件项目中的翻译、本地化和语言切换。
它们共享三个主要概念:
内容声明: 定义应用程序可翻译内容的方法。
- 在 Intlayer 中称为 content declaration file,可以是导出结构化数据的 JSON、JS 或 TS 文件。有关更多信息,请参见 Intlayer 文档。
- 在 next-intl 中称为 messages 或 locale messages,通常在 JSON 文件中。有关更多信息,请参见 next-intl 文档。
工具: 用于构建和解释应用程序中的内容声明的工具,例如 Intlayer 的 useIntlayer() 或 useLocale(),以及 next-intl 的 useTranslations()。
插件和中间件: 用于管理 URL 重定向、打包优化等功能, , 例如,Intlayer 的 intlayerMiddleware 或 next-intl 的 createMiddleware。
Intlayer 与 next-intl: 关键区别
要深入分析 Intlayer 如何与其他 i18n 库(如 next-intl)进行比较,请查看 next-i18next vs. next-intl vs. Intlayer 博客文章。
如何生成 next-intl 消息与 Intlayer
为什么使用 Intlayer 与 next-intl?
Intlayer 内容声明文件通常提供更好的开发者体验。由于两个主要优点,它们更加灵活和易于维护:
灵活的位置: 你可以将 Intlayer 内容声明文件放置在应用程序文件树的任何位置。这使得重命名或删除组件变得简单,而不会留下未使用或悬挂的消息文件。
示例文件结构:
bash复制代码复制代码到剪贴板
.└── src └── components └── MyComponent ├── index.content.ts # 内容声明文件 └── index.tsx
集中翻译: Intlayer 将所有翻译存储在一个内容声明中,确保没有翻译被遗漏。在 TypeScript 项目中,缺失翻译会自动被标记为类型错误,为开发者提供即时反馈。
安装
要一起使用 Intlayer 和 next-intl,请安装这两个库:
复制代码到剪贴板
npm install intlayer next-intl
配置 Intlayer 导出 next-intl 消息
注意: 从 Intlayer 导出消息到 next-intl 可能会引入结构上的细微差异。如果可能,保持 Intlayer 或 next-intl 单独的流程以简化集成。如果确实需要从 Intlayer 生成 next-intl 消息,请遵循以下步骤。
在项目根目录中创建或更新一个 intlayer.config.ts 文件(或 .mjs / .cjs):
复制代码到剪贴板
import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = { internationalization: { locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH], defaultLocale: Locales.ENGLISH, }, content: { dictionaryOutput: ["next-intl"], // 使用 next-intl 输出 nextIntlMessagesDir: "./intl/messages", // 保存 next-intl 消息的位置 },};export default config;
内容声明
以下是多个格式的内容声明文件示例。Intlayer 将把这些编译成 next-intl 可以使用的消息文件。
复制代码到剪贴板
import { t, type Dictionary } from "intlayer";const content = { key: "my-component", content: { helloWorld: t({ en: "Hello World", fr: "Bonjour le monde", es: "Hola Mundo", }), },} satisfies Dictionary;export default content;
构建 next-intl 消息
要构建 next-intl 的消息文件,请运行:
复制代码到剪贴板
npx intlayer dictionaries build
这将在 ./intl/messages 目录中生成资源(如 intlayer.config.* 中配置的)。预期输出:
复制代码到剪贴板
.└── intl └── messages └── zh └── my-content.json └── fr └── my-content.json └── es └── my-content.json
每个文件包含来自所有 Intlayer 内容声明的编译消息。顶级键通常与 content.key 字段匹配。
在你的 Next.js 应用中使用 next-intl
欲了解更多详细信息,请参阅官方 next-intl 使用文档。
创建中间件 (可选):
如果你想管理自动语言检测或重定向,请使用 next-intl 的 createMiddleware。middleware.ts复制代码复制代码到剪贴板
import createMiddleware from "next-intl/middleware";import { NextResponse } from "next/server";export default createMiddleware({ locales: ["en", "fr", "es"], defaultLocale: "en",});export const config = { matcher: ["/((?!api|_next|.*\\..*).*)"],};
创建一个 layout.tsx 或 _app.tsx 来加载消息:
如果你正在使用 App Router(Next.js 13+),请创建一个布局:app/[locale]/layout.tsx复制代码复制代码到剪贴板
import { NextIntlClientProvider } from 'next-intl';import { notFound } from 'next/navigation';import React, { ReactNode } from 'react';
export default async function RootLayout({
children, params}: {
children: ReactNode; params: { locale: string };}) {
let messages; try { messages = (await import(`../../intl/messages/${params.locale}.json`)).default; } catch (error) { notFound(); } return ( <html lang={params.locale}> <body> <NextIntlClientProvider locale={params.locale} messages={messages}> {children} </NextIntlClientProvider> </body> </html> );}
如果你正在使用 Pages Router(Next.js 12 或更早),请在 `_app.tsx` 中加载消息:typescript fileName="pages/_app.tsx" import type { AppProps } from 'next/app'; import { NextIntlProvider } from 'next-intl';
function MyApp({ Component, pageProps }: AppProps) {
return ( <NextIntlProvider locale={pageProps.locale} messages={pageProps.messages}> <Component {...pageProps} /> </NextIntlProvider> );}
export default MyApp;
3. **在服务器端获取消息 (Pages Router 示例):**typescript fileName="pages/index.tsx" import { GetServerSideProps } from "next"; import HomePage from "../components/HomePage";
export default HomePage;
export const getServerSideProps: GetServerSideProps = async ({ locale }) => {
const messages = (await import(`../intl/messages/${locale}.json`)).default; return { props: { locale, messages, }, };};
### 在 Next.js 组件中使用内容 一旦消息被加载到 next-intl 中,你可以通过 `useTranslations()` 钩子在组件中使用它们:typescript fileName="src/components/MyComponent/index.tsx" codeFormat="typescript" import type { FC } from "react"; import { useTranslations } from 'next-intl';
const MyComponent: FC = () => { const t = useTranslations('my-component'); // 'my-component' 对应于 Intlayer 中的内容键
return (
<div> <h1>{t('helloWorld')}</h1> </div>); };
export default MyComponent;
jsx fileName="src/components/MyComponent/index.jsx" codeFormat="esm" import { useTranslations } from "next-intl";
export default function MyComponent() { const t = useTranslations("my-component");
return (
<div> <h1>{t("helloWorld")}</h1> </div>); }
**就这些!** 每当你更新或添加新的 Intlayer 内容声明文件时,重新运行 `intlayer build` 命令以重新生成你的 next-intl JSON 消息。next-intl 将自动获取更新的内容。