223 lines
6.8 KiB
Plaintext
223 lines
6.8 KiB
Plaintext
---
|
|
title: I18n
|
|
label: I18n
|
|
order: 40
|
|
desc: Manage and customize internationalization support in your CMS editor experience
|
|
keywords: internationalization, i18n, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
|
---
|
|
|
|
Not only does Payload support managing localized content, it also has internationalization support so that admin users can work in their preferred language.
|
|
|
|
By default, Payload comes with English installed as the language it uses. But, you can import and pass other languages to the Payload config as well. It's best to only support the languages that you need, because that way, the bundled JavaScript is kept to a minimum for your project.
|
|
|
|
Here's an example for how to pass additional languages to Payload for use in translating:
|
|
|
|
```ts
|
|
import { buildConfig } from 'payload'
|
|
import { en } from 'payload/i18n/en'
|
|
import { de } from 'payload/i18n/de'
|
|
|
|
export default buildConfig({
|
|
/**
|
|
* Payload accepts specific translations to use.
|
|
* This is completely optional and will default to English if not provided
|
|
*/
|
|
i18n: {
|
|
// Payload will support either English or German,
|
|
// able to be specified in preferences on a user-by-user basis
|
|
supportedLanguages: { en, de },
|
|
},
|
|
|
|
// .. the rest of your config
|
|
})
|
|
```
|
|
|
|
|
|
### Configuration Options
|
|
|
|
In your Payload config, you can add translations and customize the settings in `i18n`. Payload will use your custom options and merge it with the default, allowing you to override the settings Payload provides.
|
|
|
|
**Example Payload config extending i18n:**
|
|
|
|
```ts
|
|
import { buildConfig } from 'payload/config'
|
|
|
|
export default buildConfig({
|
|
//...
|
|
i18n: {
|
|
fallbackLng: 'en', // default
|
|
debug: false, // default
|
|
resources: {
|
|
en: {
|
|
custom: {
|
|
// namespace can be anything you want
|
|
key1: 'Translation with {{variable}}', // translation
|
|
},
|
|
// override existing translation keys
|
|
general: {
|
|
dashboard: 'Home',
|
|
},
|
|
},
|
|
},
|
|
},
|
|
//...
|
|
})
|
|
```
|
|
|
|
While Payload's built-in features come translated, you may want to also translate parts of your project's configuration too. This is possible in places like Collections and Globals labels and groups, field labels, descriptions and input placeholder text. The admin UI will display all the correct translations you provide based on the user's language.
|
|
|
|
Here is an example of a simple collection supporting both English and Spanish editors:
|
|
|
|
```ts
|
|
import { CollectionConfig } from 'payload'
|
|
|
|
export const Articles: CollectionConfig = {
|
|
slug: 'articles',
|
|
labels: {
|
|
singular: {
|
|
en: 'Article',
|
|
es: 'Artículo',
|
|
},
|
|
plural: {
|
|
en: 'Articles',
|
|
es: 'Artículos',
|
|
},
|
|
},
|
|
admin: {
|
|
group: { en: 'Content', es: 'Contenido' },
|
|
},
|
|
fields: [
|
|
{
|
|
name: 'title',
|
|
type: 'text',
|
|
label: {
|
|
en: 'Title',
|
|
es: 'Título',
|
|
},
|
|
admin: {
|
|
placeholder: { en: 'Enter title', es: 'Introduce el título' },
|
|
},
|
|
},
|
|
{
|
|
name: 'type',
|
|
type: 'radio',
|
|
options: [
|
|
{
|
|
value: 'news',
|
|
label: { en: 'News', es: 'Noticias' },
|
|
}, // etc...
|
|
],
|
|
},
|
|
],
|
|
}
|
|
```
|
|
|
|
## Admin UI
|
|
|
|
The [Admin Panel](../admin/overview) reads the language settings of a user's browser and display all text in that language, or will fall back to English if the user's language is not yet supported.
|
|
After a user logs in, they can change their language selection in the `/account` view.
|
|
|
|
<Banner>
|
|
<strong>Note:</strong>
|
|
<br />
|
|
If there is a language that Payload does not yet support, we accept code
|
|
[contributions](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md). You can also make and import your own translation files.
|
|
</Banner>
|
|
|
|
## Node
|
|
|
|
Payload's backend sets the language on incoming requests before they are handled. This allows backend validation to return error messages in the user's own language or system generated emails to be sent using the correct translation. You can make HTTP requests with the `accept-language` header and Payload will use that language.
|
|
|
|
Anywhere in your Payload app that you have access to the `req` object, you can access payload's extensive internationalization features assigned to `req.i18n`. To access text translations you can use `req.t('namespace:key')`.
|
|
|
|
## Configuration Options
|
|
|
|
In your Payload config, you can add translations and customize the settings in `i18n`. Payload will use your custom options and merge it with the default, allowing you to override the settings Payload provides.
|
|
|
|
**Example Payload config extending i18n:**
|
|
|
|
```ts
|
|
import { buildConfig } from 'payload'
|
|
|
|
export default buildConfig({
|
|
//...
|
|
i18n: {
|
|
fallbackLanguage: 'en', // default
|
|
translations: {
|
|
en: {
|
|
custom: {
|
|
// namespace can be anything you want
|
|
key1: 'Translation with {{variable}}', // translation
|
|
},
|
|
// override existing translation keys
|
|
general: {
|
|
dashboard: 'Home',
|
|
},
|
|
},
|
|
},
|
|
},
|
|
//...
|
|
})
|
|
```
|
|
|
|
## Types for custom translations
|
|
|
|
In order to use custom translations in your project, you need to provide the types for the translations. Here is an example of how you can define the types for the custom translations in a custom react component:
|
|
|
|
```ts
|
|
'use client'
|
|
import type { NestedKeysStripped } from '@payloadcms/translations'
|
|
import type React from 'react'
|
|
|
|
import { useTranslation } from '@payloadcms/ui/providers/Translation'
|
|
|
|
const customTranslations = {
|
|
en: {
|
|
general: {
|
|
test: 'Custom Translation',
|
|
},
|
|
},
|
|
}
|
|
|
|
type CustomTranslationObject = typeof customTranslations.en
|
|
type CustomTranslationKeys = NestedKeysStripped<CustomTranslationObject>
|
|
|
|
export const MyComponent: React.FC = () => {
|
|
const { i18n, t } = useTranslation<CustomTranslationObject, CustomTranslationKeys>() // These generics merge your custom translations with the default client translations
|
|
|
|
return t('general:test')
|
|
}
|
|
|
|
```
|
|
|
|
Additionally, payload exposes the `t` function in various places, for example in labels. Here is how you would type those:
|
|
|
|
```ts
|
|
import type {
|
|
DefaultTranslationKeys,
|
|
NestedKeysStripped,
|
|
TFunction,
|
|
} from '@payloadcms/translations'
|
|
import type { Field } from 'payload/types'
|
|
|
|
const customTranslations = {
|
|
en: {
|
|
general: {
|
|
test: 'Custom Translation',
|
|
},
|
|
},
|
|
}
|
|
|
|
type CustomTranslationObject = typeof customTranslations.en
|
|
type CustomTranslationKeys = NestedKeysStripped<CustomTranslationObject>
|
|
|
|
const field: Field = {
|
|
name: 'myField',
|
|
type: 'text',
|
|
label: (
|
|
{ t }: { t: TFunction<CustomTranslationKeys | DefaultTranslationKeys> }, // The generic passed to TFunction does not automatically merge the custom translations with the default translations. We need to merge them ourselves here
|
|
) => t('fields:addLabel'),
|
|
}
|
|
```
|
|
|