docs: filterAvailableLocales (#11031)

Adding documentation and tests missing in PR #11007

---------

Co-authored-by: Jarrod Flesch <jarrodmflesch@gmail.com>
Co-authored-by: Jarrod Flesch <30633324+JarrodMFlesch@users.noreply.github.com>
This commit is contained in:
Dan Ribbens
2025-02-12 14:48:12 -05:00
committed by GitHub
parent 6bfa66c9ff
commit 3131dba039
4 changed files with 52 additions and 8 deletions

View File

@@ -77,11 +77,12 @@ export default buildConfig({
The following options are available:
| Option | Description |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **`locales`** | Array of all the languages that you would like to support. [More details](#locales) |
| **`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 unless a fallback is explicitly provided in the request. True by default. |
| Option | Description |
|------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **`locales`** | Array of all the languages that you would like to support. [More details](#locales) |
| **`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 unless a fallback is explicitly provided in the request. True by default. |
| **`filterAvailableLocales`** | A function that is called with the array of `locales` and the `req`, it should return locales to show in admin UI selector. [See more](#filter-available-options). |
### Locales
@@ -100,6 +101,35 @@ The locale codes do not need to be in any specific format. It's up to you to def
_* An asterisk denotes that a property is required._
#### Filter Available Options
In some projects you may want to filter the available locales shown in the admin UI selector. You can do this by providing a `filterAvailableLocales` function in your Payload Config. This is called on the server side and is passed the array of locales. This means that you can determine what locales are visible in the localizer selection menu at the top of the admin panel. You could do this per user, or implement a function that scopes these to tenants and more. Here is an example using request headers in a multi-tenant application:
```ts
// ... rest of payload config
localization: {
defaultLocale: 'en',
locales: ['en', 'es'],
filterAvailableLocales: async ({ req, locales }) => {
if (getTenantFromCookie(req.headers, 'text')) {
const fullTenant = await req.payload.findByID({
id: getTenantFromCookie(req.headers, 'text') as string,
collection: 'tenants',
req,
})
if (fullTenant && fullTenant.supportedLocales?.length) {
return locales.filter((locale) => {
return fullTenant.supportedLocales?.includes(locale.code as 'en' | 'es')
})
}
}
return locales
},
}
```
Since the filtering happens at the root level of the application and its result is not calculated every time you navigate to a new page, you may want to call `router.refresh` in a custom component that watches when values that affect the result change. In the example above, you would want to do this when `supportedLocales` changes on the tenant document.
## 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.

View File

@@ -414,9 +414,16 @@ export default buildConfigWithDefaults({
},
],
localization: {
filterAvailableLocales: ({ locales }) => {
return locales.filter((locale) => locale.code !== 'xx')
},
defaultLocale,
fallback: true,
locales: [
{
code: 'xx',
label: 'FILTERED',
},
{
code: defaultLocale,
label: 'English',

View File

@@ -97,7 +97,7 @@ describe('Localization', () => {
// })
})
describe('localizer', async () => {
describe('localizer', () => {
test('should show localizer controls', async () => {
await page.goto(url.create)
await expect(page.locator('.localizer.app-header__localizer')).toBeVisible()
@@ -105,6 +105,13 @@ describe('Localization', () => {
await expect(page.locator('.localizer .popup.popup--active')).toBeVisible()
})
test('should filter locale with filterAvailableLocales', async () => {
await page.goto(url.create)
await expect(page.locator('.localizer.app-header__localizer')).toBeVisible()
await page.locator('.localizer >> button').first().click()
await expect(page.locator('.localizer .popup.popup--active')).not.toContainText('FILTERED')
})
test('should disable control for active locale', async () => {
await page.goto(url.create)
@@ -472,7 +479,7 @@ describe('Localization', () => {
await runCopy(page)
await expect(page.locator('#field-title')).toHaveValue(title)
const regexPattern = new RegExp(`locale=es`)
const regexPattern = /locale=es/
await expect(page).toHaveURL(regexPattern)
await openCopyToLocaleDrawer(page)

View File

@@ -68,7 +68,7 @@ export interface Config {
'global-array': GlobalArraySelect<false> | GlobalArraySelect<true>;
'global-text': GlobalTextSelect<false> | GlobalTextSelect<true>;
};
locale: 'en' | 'es' | 'pt' | 'ar' | 'hu';
locale: 'xx' | 'en' | 'es' | 'pt' | 'ar' | 'hu';
user: User & {
collection: 'users';
};