1. Documentation
    2. 环境
    3. Intlayer与Next.js

    开始使用 Intlayer 和 Next.js 15 应用路由进行国际化 (i18n)

    什么是 Intlayer?

    Intlayer 是一个创新的开源国际化 (i18n) 库,旨在简化现代 web 应用程序中的多语言支持。Intlayer 与最新的 Next.js 15 框架无缝集成,包括其强大的 应用路由器。它经过优化以与 服务器组件 一起高效渲染,并且与 Turbopack 完全兼容。

    使用 Intlayer,您可以:

    • 轻松管理翻译,在组件级别使用声明性字典。
    • 动态本地化元数据、路由和内容。
    • 访问客户端和服务器端组件中的翻译
    • 确保 TypeScript 支持,通过自动生成类型,提高自动补全和错误检测。
    • 利用高级功能,如动态区域检测和切换。

    注意:Intlayer 与 Next.js 12、13、14 和 15 兼容。如果您使用 Next.js 页面路由,可以参考此 指南。对于使用应用路由的 Next.js 12、13、14,请参考此 指南


    在 Next.js 应用程序中设置 Intlayer 的逐步指南

    步骤 1:安装依赖

    使用 npm 安装必要的软件包:

    bash
    1npm install intlayer next-intlayer
    bash
    1yarn add intlayer next-intlayer
    bash
    1pnpm add intlayer next-intlayer

    步骤 2:配置您的项目

    创建一个配置文件来配置您的应用程序的语言:

    typescript
    1// intlayer.config.ts 2 3import { Locales, type IntlayerConfig } from "intlayer"; 4 5const config: IntlayerConfig = { 6 internationalization: { 7 locales: [ 8 Locales.ENGLISH, 9 Locales.FRENCH, 10 Locales.SPANISH, 11 // 其他地方语言 12 ], 13 defaultLocale: Locales.ENGLISH, 14 }, 15}; 16 17export default config;

    要查看所有可用参数,请参阅 配置文档

    步骤 3:在您的 Next.js 配置中集成 Intlayer

    配置您的 Next.js 设置以使用 Intlayer:

    typescript
    1// next.config.mjs 2import { withIntlayer } from "next-intlayer/server"; 3 4/** @type {import('next').NextConfig} */ 5const nextConfig = {}; 6 7export default withIntlayer(nextConfig);

    步骤 4:配置中间件以进行地区检测

    设置中间件以检测用户的首选语言:

    typescript
    1// src/middleware.ts 2export { intlayerMiddleware as middleware } from "next-intlayer/middleware"; 3 4export const config = { 5 matcher: "/((?!api|static|.*\\..*|_next).*)", 6};

    步骤 5:定义动态区域路由

    实现本地化内容的动态路由:

    src/app/page.ts 更改为 src/app/[locale]/page.ts

    然后,在您的应用程序布局中实现 generateStaticParams 函数。

    tsx
    1// src/app/layout.tsx 2 3import type { ReactNode } from "react"; 4import "./globals.css"; 5 6export { generateStaticParams } from "next-intlayer"; // 插入行 7 8const RootLayout = ({ 9 children, 10}: Readonly<{ 11 children: ReactNode; 12}>) => children; 13 14export default RootLayout;

    接着在您的 [locale] 目录中添加一个新布局:

    tsx
    1// src/app/[locale]/layout.tsx 2 3import { type NextLayoutIntlayer } from "next-intlayer"; 4import { Inter } from "next/font/google"; 5import { getHTMLTextDir } from "intlayer"; 6 7const inter = Inter({ subsets: ["latin"] }); 8 9const LocaleLayout: NextLayoutIntlayer = async ({ children, params }) => { 10 const { locale } = await params; 11 return ( 12 <html lang={locale} dir={getHTMLTextDir(locale)}> 13 <body className={inter.className}>{children}</body> 14 </html> 15 ); 16}; 17 18export default LocaleLayout;

    步骤 6:声明您的内容

    创建和管理您的内容字典:

    tsx
    1// src/app/[locale]/page.content.ts 2import { t, type DeclarationContent } from "intlayer"; 3 4const pageContent = { 5 key: "page", 6 content: { 7 getStarted: { 8 main: t({ 9 en: "Get started by editing", 10 fr: "Commencez par éditer", 11 es: "Comience por editar", 12 }), 13 pageLink: "src/app/page.tsx", 14 }, 15 }, 16} satisfies DeclarationContent; 17 18export default pageContent;

    查看如何声明您的 Intlayer 声明文件

    步骤 7:在您的代码中利用内容

    在您的应用程序中访问内容字典:

    tsx
    1// src/app/[locale]/page.ts 2 3import { ClientComponentExample } from "@component/ClientComponentExample"; 4import { LocaleSwitcher } from "@component/LangSwitcherDropDown"; 5import { NestedServerComponentExample } from "@component/NestedServerComponentExample"; 6import { ServerComponentExample } from "@component/ServerComponentExample"; 7import { type NextPageIntlayer, IntlayerClientProvider } from "next-intlayer"; 8import { IntlayerServerProvider, useIntlayer } from "next-intlayer/server"; 9 10const PageContent = () => { 11 const { title, content } = useIntlayer("page"); 12 13 return ( 14 <> 15 <p>{content.getStarted.main}</p> 16 <code>{content.getStarted.pageLink}</code> 17 </> 18 ); 19}; 20 21const Page: NextPageIntlayer = async ({ params }) => { 22 const { locale } = await params; 23 24 return ( 25 <> 26 {/** 27 * IntlayerServerProvider 用于将语言传递给服务器子组件 28 * 如果设置在布局中则无效 29 */} 30 <IntlayerServerProvider locale={locale}> 31 <PageContent /> 32 <ServerComponentExample /> 33 </IntlayerServerProvider> 34 {/** 35 * IntlayerClientProvider 用于将语言传递给客户端子组件 36 * 可以设置在任何父组件中,包括布局 37 */} 38 <IntlayerClientProvider locale={locale}> 39 <ClientComponentExample /> 40 </IntlayerClientProvider> 41 </> 42 ); 43}; 44 45export default Page;
    tsx
    1// src/components/ClientComponentExample.tsx 2 3"use client"; 4 5import { useIntlayer } from "next-intlayer"; 6 7export const ClientComponentExample = () => { 8 const content = useIntlayer("client-component-example"); // 创建相关内容声明 9 10 return ( 11 <div> 12 <h2>{content.title} </h2> 13 <p>{content.content}</p> 14 </div> 15 ); 16};
    tsx
    1// src/components/ServerComponentExample.tsx 2 3import { useIntlayer } from "next-intlayer/server"; 4 5export const ServerComponentExample = () => { 6 const content = useIntlayer("server-component-example"); // 创建相关内容声明 7 8 return ( 9 <div> 10 <h2>{content.title} </h2> 11 <p>{content.content}</p> 12 </div> 13 ); 14};

    注意:如果您想在 string 属性(例如 alttitlehrefaria-label 等)中使用您的内容,您必须调用函数的值,例如:

    tsx
    1<img src={content.image.src.value} alt={content.image.value} />

    有关在客户端或服务器组件中更详细的使用示例,请参阅 Next.js 示例

    (可选)步骤 8:国际化您的元数据

    如果您想国际化您的元数据,例如页面的标题,您可以使用 Next.js 提供的 generateMetadata 函数。在函数内部,使用 getTranslationContent 函数翻译您的元数据。

    typescript
    1// src/app/[locale]/layout.tsx 或 src/app/[locale]/page.tsx 2 3import { 4 type IConfigLocales, 5 getTranslationContent, 6 getMultilingualUrls, 7} from "intlayer"; 8import type { Metadata } from "next"; 9import type { LocalParams } from "next-intlayer"; 10 11export const generateMetadata = ({ 12 params: { locale }, 13}: LocalParams): Metadata => { 14 const t = <T>(content: IConfigLocales<T>) => 15 getTranslationContent(content, locale); 16 17 /** 18 * 生成一个对象,包含每个语言的所有 URL。 19 * 20 * 示例: 21 * ```ts 22 * getMultilingualUrls('/about'); 23 * 24 * // 返回 25 * // { 26 * // en: '/about', 27 * // fr: '/fr/about', 28 * // es: '/es/about', 29 * // } 30 * ``` 31 */ 32 const multilingualUrls = getMultilingualUrls("/"); 33 34 return { 35 title: t<string>({ 36 en: "My title", 37 fr: "Mon titre", 38 es: "Mi título", 39 }), 40 description: t({ 41 en: "My description", 42 fr: "Ma description", 43 es: "Mi descripción", 44 }), 45 alternates: { 46 canonical: url, 47 languages: { ...multilingualUrls, "x-default": "/" }, 48 }, 49 openGraph: { 50 url: multilingualUrls[locale], 51 }, 52 }; 53}; 54 55// ... 其余代码

    了解更多有关元数据优化的信息,请访问 官方 Next.js 文档

    (可选)步骤 9:国际化您的 sitemap.xml 和 robots.txt

    要国际化您的 sitemap.xmlrobots.txt,您可以使用 Intlayer 提供的 getMultilingualUrls 函数。该函数允许您为 sitemap 生成多语言 URL。

    tsx
    1// src/app/sitemap.ts 2 3import { getMultilingualUrls } from "intlayer"; 4import type { MetadataRoute } from "next"; 5 6const sitemap = (): MetadataRoute.Sitemap => [ 7 { 8 url: "https://example.com", 9 alternates: { 10 languages: getMultilingualUrls("https://example.com"), 11 }, 12 }, 13 { 14 url: "https://example.com/login", 15 alternates: { 16 languages: getMultilingualUrls("https://example.com/login"), 17 }, 18 }, 19 { 20 url: "https://example.com/register", 21 alternates: { 22 languages: getMultilingualUrls("https://example.com/register"), 23 }, 24 }, 25]; 26 27export default sitemap;
    tsx
    1// src/app/robots.ts 2import type { MetadataRoute } from "next"; 3import { getMultilingualUrls } from "intlayer"; 4 5const getAllMultilingualUrls = (urls: string[]) => 6 urls.flatMap((url) => Object.values(getMultilingualUrls(url)) as string[]); 7 8const robots = (): MetadataRoute.Robots => ({ 9 rules: { 10 userAgent: "*", 11 allow: ["/"], 12 disallow: getAllMultilingualUrls(["/login", "/register"]), 13 }, 14 host: "https://example.com", 15 sitemap: `https://example.com/sitemap.xml`, 16}); 17 18export default robots;

    了解更多有关 sitemap 优化的信息,请访问 官方 Next.js 文档。了解更多有关 robots.txt 优化的信息,请访问 官方 Next.js 文档

    (可选)步骤 10:更改内容的语言

    要更改内容的语言,您可以使用 useLocale 钩子提供的 setLocale 函数。此函数允许您设置应用程序的语言并相应地更新内容。

    tsx
    1import { Locales } from "intlayer"; 2import { useLocale } from "next-intlayer"; 3 4const MyComponent = () => { 5 const { setLocale } = useLocale(); 6 7 return <button onClick={() => setLocale(Locales.English)}>更改语言</button>; 8};

    配置 TypeScript

    Intlayer 使用模块增强来获得 TypeScript 的好处,并使您的代码库更强大。

    alt text

    alt text

    确保你的 TypeScript 配置包含自动生成的类型。

    json5
    1// tsconfig.json 2 3{ 4 // 您的自定义配置 5 include: [ 6 "src", 7 "types", // <- 包含自动生成的类型 8 ], 9}

    Git 配置

    建议忽略 Intlayer 生成的文件。这允许您避免将其提交到 Git 存储库。

    为此,您可以将以下指令添加到您的 .gitignore 文件中:

    gitignore
    1# 忽略 Intlayer 生成的文件 2.intlayer

    如果您有改善此文档的想法,请随时通过在GitHub上提交拉取请求来贡献。

    文档的 GitHub 链接

    在此页面