I18n

Admin Panel 已支持超过 30 种语言且持续增加。通过 I18n 功能,编辑者可以使用首选语言浏览界面并阅读 API 错误信息。这与 Localization 类似,但不同之处在于:I18n 管理的是应用程序界面的翻译,而非数据本身的翻译。

默认情况下,Payload 预装了英语支持,但你可以轻松为应用程序加载其他语言。系统会根据请求自动检测语言。如果未检测到语言,或者用户使用的语言尚未被你的应用程序支持,系统将默认选择英语。

要为项目添加 I18n 支持,首先需要安装 @payloadcms/translations 包:

pnpm install @payloadcms/translations

安装完成后,可以在 Payload Config 中使用 i18n 键进行配置:

import { buildConfig } from 'payload'

export default buildConfig({
  // ...
  i18n: {
    // highlight-line
    // ...
  },
})

注意: 如果 Payload 尚未支持你需要的语言,我们欢迎 代码贡献

配置选项

你可以轻松自定义和覆盖 Payload 默认提供的任何 i18n 设置。Payload 会使用你的自定义选项并将其与自身的设置合并。

import { buildConfig } from 'payload'

export default buildConfig({
  // ...
  // highlight-start
  i18n: {
    fallbackLanguage: 'en', // 默认值
  },
  // highlight-end
})

以下是可用的配置选项:

OptionDescription
fallbackLanguage当用户首选语言不被支持时的回退语言。默认为 'en'
translations包含翻译文本的对象。键是语言代码,值是对应的翻译内容。
supportedLanguages包含支持语言的对象。键是语言代码,值是对应的翻译内容。

添加语言

你可以通过提供新语言的翻译,轻松地为 Payload 应用添加新语言。Payload 维护了一系列内置翻译,可以从 @payloadcms/translations 导入,但你也可以提供自己的自定义翻译来支持任何语言。

要添加新语言,请在 Payload 配置 中使用 i18n.supportedLanguages 键:

import { buildConfig } from 'payload'
import { en } from '@payloadcms/translations/languages/en'
import { de } from '@payloadcms/translations/languages/de'

export default buildConfig({
  // ...
  // highlight-start
  i18n: {
    supportedLanguages: { en, de },
  },
  // highlight-end
})

提示: 最好只支持你需要的语言,这样可以为项目保持最小的 JavaScript 打包体积。

自定义翻译

你可以通过扩展现有语言或完全添加新语言来自定义 Payload 的内置翻译。这可以通过向现有语言注入新的翻译字符串,或者提供全新的语言键来实现。

要添加自定义翻译,请在 Payload 配置 中使用 i18n.translations 键:

import { buildConfig } from 'payload'

export default buildConfig({
  //...
  i18n: {
    // highlight-start
    translations: {
      en: {
        custom: {
          // 命名空间可以是任意你想要的名称
          key1: '包含 {{variable}} 的翻译', // 翻译文本
        },
        // 覆盖现有的翻译键
        general: {
          dashboard: '首页',
        },
      },
    },
    // highlight-end
  },
  //...
})

项目翻译

虽然 Payload 的内置功能已经提供了完整的翻译支持,但你可能还需要翻译自己项目的部分内容。这可以在 CollectionsGlobals 等地方实现,例如对它们的标签和分组、字段标签、描述或输入占位符文本进行翻译。

要实现这一点,只需在适用的地方提供按语言代码组织的翻译:

import type { CollectionConfig } from 'payload'

export const Articles: CollectionConfig = {
  slug: 'articles',
  labels: {
    singular: {
      // highlight-start
      en: 'Article',
      es: 'Artículo',
      // highlight-end
    },
    plural: {
      // highlight-start
      en: 'Articles',
      es: 'Artículos',
      // highlight-end
    },
  },
  admin: {
    group: {
      // highlight-start
      en: 'Content',
      es: 'Contenido',
      // highlight-end
    },
  },
  fields: [
    {
      name: 'title',
      type: 'text',
      label: {
        // highlight-start
        en: 'Title',
        es: 'Título',
        // highlight-end
      },
      admin: {
        placeholder: {
          // highlight-start
          en: 'Enter title',
          es: 'Introduce el título',
          // highlight-end
        },
      },
    },
  ],
}

更改语言

用户可以在账户设置中更改首选语言,或者通过操作他们的 用户偏好设置 来修改。

Node.js#node

Payload 的后端会在处理传入请求之前设置语言。这使得后端验证可以返回用户自身语言的错误信息,或者系统生成的电子邮件能够使用正确的翻译发送。你可以通过 accept-language 请求头发起 HTTP 请求,Payload 将使用该语言。

在 Payload 应用中任何可以访问 req 对象的地方,你都可以使用分配给 req.i18n 的丰富国际化功能。要访问文本翻译,可以使用 req.t('namespace:key')

TypeScript

要在项目中使用自定义翻译,你需要为翻译提供类型定义。

这里我们创建一个可共享的翻译对象。我们将在自定义组件和 Payload 配置中导入这个对象。

以下示例展示了如何扩展英文翻译,但你可以对任何语言进行同样的操作。

// <rootDir>/custom-translations.ts

import { enTranslations } from '@payloadcms/translations/languages/en'
import type { NestedKeysStripped } from '@payloadcms/translations'

export const customTranslations = {
  en: {
    general: {
      myCustomKey: '我的自定义英文翻译',
    },
    fields: {
      addLabel: '添加!',
    },
  },
}

export type CustomTranslationsObject = typeof customTranslations.en &
  typeof enTranslations
export type CustomTranslationsKeys =
  NestedKeysStripped<CustomTranslationsObject>

将共享的翻译对象导入到 Payload 配置中以便使用:

// <rootDir>/payload.config.ts

import { buildConfig } from 'payload'

import { customTranslations } from './custom-translations'

export default buildConfig({
  //...
  i18n: {
    translations: customTranslations,
  },
  //...
})

将共享的翻译类型导入到自定义组件中使用:

// <rootDir>/components/MyComponent.tsx

'use client'
import type React from 'react'
import { useTranslation } from '@payloadcms/ui'

import type {
  CustomTranslationsObject,
  CustomTranslationsKeys,
} from '../custom-translations'

export const MyComponent: React.FC = () => {
  const { i18n, t } = useTranslation<
    CustomTranslationsObject,
    CustomTranslationsKeys
  >() // 这些泛型会将你的自定义翻译与默认的客户端翻译合并

  return t('general:myCustomKey')
}

此外,Payload 在多个地方暴露了 t 函数,例如在标签中。以下是这些情况的类型定义方式:

// <rootDir>/fields/myField.ts

import type {
  DefaultTranslationKeys,
  TFunction,
} from '@payloadcms/translations'
import type { Field } from 'payload'

import { CustomTranslationsKeys } from '../custom-translations'

const field: Field = {
  name: 'myField',
  type: 'text',
  label: ({ t: defaultT }) => {
    const t = defaultT as TFunction<CustomTranslationsKeys>
    return t('fields:addLabel')
  },
}