Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

Localization

Payload features deep field-based localization support. Maintaining as many locales as you need is easy. All localization support is opt-in by default. To do so, follow the two steps below.

Enabling in the Payload config

Add the localization property to your Payload config to enable localization project-wide. You'll need to provide a list of all locales that you'd like to support as well as set a few other options.

Example Payload config set up for localization:

1
import { buildConfig } from 'payload/config'
2
3
export default buildConfig({
4
collections: [
5
// collections go here
6
],
7
localization: {
8
locales: ['en', 'es', 'de'], // required
9
defaultLocale: 'en', // required
10
fallback: true,
11
},
12
})

Example Payload config set up for localization with full locales objects:

1
import { buildConfig } from 'payload/config'
2
3
export default buildConfig({
4
collections: [
5
// collections go here
6
],
7
localization: {
8
locales: [
9
{
10
label: 'English',
11
code: 'en',
12
},
13
{
14
label: 'Arabic',
15
code: 'ar',
16
// opt-in to setting default text-alignment on Input fields to rtl (right-to-left)
17
// when current locale is rtl
18
rtl: true,
19
},
20
],
21
defaultLocale: 'en', // required
22
fallback: true,
23
},
24
})

Example Payload config set up for localization with full locales objects ( including internationalization support):

1
import { buildConfig } from 'payload/config'
2
3
export default buildConfig({
4
collections: [
5
// collections go here
6
],
7
localization: {
8
locales: [
9
{
10
label: {
11
en: 'English', // English label
12
nb: 'Engelsk', // Norwegian label
13
},
14
code: 'en',
15
},
16
{
17
label: {
18
en: 'Norwegian', // English label
19
nb: 'Norsk', // Norwegian label
20
},
21
code: 'nb',
22
},
23
],
24
defaultLocale: 'en', // required
25
fallback: true,
26
},
27
})

Here is a brief explanation of each of the options available within the localization property:

locales

Array-based list of all the languages that you would like to support. This can be an array containing strings for each language code you want your project to store and serve or objects with a label, a locale code, rtl ( right-to-left), and fallbackLocale property. The locale codes do not need to be in any specific format. It's up to you to define how to represent your locales. Common patterns are to use two-letter ISO 639 language codes or four-letter language and country codes (ISO 3166‑1) such as en-US, en-UK, es-MX, etc.

Locale Properties:

OptionDescription
code *Unique code to identify the language throughout the APIs for locale and fallbackLocale
labelA string to use for the selector when choosing a language, or an object keyed on the i18n keys for different languages in use.
rtlA boolean that when true will make the admin UI display in Right-To-Left.
fallbackLocaleThe code for this language to fallback to when properties of a document are not present.

* An asterisk denotes that a property is required.

defaultLocale

Required string that matches one of the locale codes from the array provided. By default, if no locale is specified, documents will be returned in this locale.

fallback

Boolean enabling "fallback" locale functionality. If a document is requested in a locale, but a field does not have a localized value corresponding to the requested locale, then if this property is enabled, the document will automatically fall back to the fallback locale value. If this property is not enabled, the value will not be populated.

Field by field localization

Payload localization works on a field level—not a document level. In addition to configuring the base Payload config to support localization, you need to specify each field that you would like to localize.

Here is an example of how to enable localization for a field:

1
{
2
name: 'title',
3
type: 'text',
4
localized: true,
5
}

With the above configuration, the title field will now be saved in the database as an object of all locales instead of a single string.

All field types with a name property support the localized property—even the more complex field types like arrays and blocks.

Retrieving localized docs

When retrieving documents, you can specify which locale you'd like to receive as well as which fallback locale should be used.

REST API

REST API locale functionality relies on URL query parameters.

?locale=

Specify your desired locale by providing the locale query parameter directly in the endpoint URL.

?fallback-locale=

Specify fallback locale to be used by providing the fallback-locale query parameter. This can be provided as either a valid locale as provided to your base Payload config, or 'null', 'false', or 'none' to disable falling back.

Example:

1
fetch('https://localhost:3000/api/pages?locale=es&fallback-locale=none');
GraphQL API

In the GraphQL API, you can specify locale and fallbackLocale args to all relevant queries and mutations.

The locale arg will only accept valid locales, but locales will be formatted automatically as valid GraphQL enum values (dashes or special characters will be converted to underscores, spaces will be removed, etc.). If you are curious to see how locales are auto-formatted, you can use the GraphQL playground.

The fallbackLocale arg will accept valid locales as well as none to disable falling back.

Example:

1
query {
2
Posts(locale: de, fallbackLocale: none) {
3
docs {
4
title
5
}
6
}
7
}
Local API

You can specify locale as well as fallbackLocale within the Local API as well as properties on the options argument. The locale property will accept any valid locale, and the fallbackLocale property will accept any valid locale as well as 'null', 'false', false, and 'none'.

Example:

1
const posts = await payload.find({
2
collection: 'posts',
3
locale: 'es',
4
fallbackLocale: false,
5
})
Next

Express