perf: ensure unnecessary config translations are not sent to the client (#10524)
This will reduce the size of the initial HTML
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import type { AcceptedLanguages } from '@payloadcms/translations'
|
import type { AcceptedLanguages } from '@payloadcms/translations'
|
||||||
import type { ImportMap, SanitizedConfig, ServerFunctionClient } from 'payload'
|
import type { ImportMap, LanguageOptions, SanitizedConfig, ServerFunctionClient } from 'payload'
|
||||||
|
|
||||||
import { rtlLanguages } from '@payloadcms/translations'
|
import { rtlLanguages } from '@payloadcms/translations'
|
||||||
import { RootProvider } from '@payloadcms/ui'
|
import { RootProvider } from '@payloadcms/ui'
|
||||||
@@ -60,19 +60,18 @@ export const RootLayout = async ({
|
|||||||
? 'RTL'
|
? 'RTL'
|
||||||
: 'LTR'
|
: 'LTR'
|
||||||
|
|
||||||
const languageOptions = Object.entries(config.i18n.supportedLanguages || {}).reduce(
|
const languageOptions: LanguageOptions = Object.entries(
|
||||||
(acc, [language, languageConfig]) => {
|
config.i18n.supportedLanguages || {},
|
||||||
if (Object.keys(config.i18n.supportedLanguages).includes(language)) {
|
).reduce((acc, [language, languageConfig]) => {
|
||||||
acc.push({
|
if (Object.keys(config.i18n.supportedLanguages).includes(language)) {
|
||||||
label: languageConfig.translations.general.thisLanguage,
|
acc.push({
|
||||||
value: language,
|
label: languageConfig.translations.general.thisLanguage,
|
||||||
})
|
value: language,
|
||||||
}
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return acc
|
return acc
|
||||||
},
|
}, [])
|
||||||
[],
|
|
||||||
)
|
|
||||||
|
|
||||||
async function switchLanguageServerAction(lang: string): Promise<void> {
|
async function switchLanguageServerAction(lang: string): Promise<void> {
|
||||||
'use server'
|
'use server'
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export type ServerOnlyRootProperties = keyof Pick<
|
|||||||
| 'endpoints'
|
| 'endpoints'
|
||||||
| 'graphQL'
|
| 'graphQL'
|
||||||
| 'hooks'
|
| 'hooks'
|
||||||
|
| 'i18n'
|
||||||
| 'jobs'
|
| 'jobs'
|
||||||
| 'logger'
|
| 'logger'
|
||||||
| 'onInit'
|
| 'onInit'
|
||||||
@@ -44,7 +45,6 @@ export type ClientConfig = {
|
|||||||
collections: ClientCollectionConfig[]
|
collections: ClientCollectionConfig[]
|
||||||
custom?: Record<string, any>
|
custom?: Record<string, any>
|
||||||
globals: ClientGlobalConfig[]
|
globals: ClientGlobalConfig[]
|
||||||
i18n?: Omit<SanitizedConfig['i18n'], 'supportedLanguages'>
|
|
||||||
} & Omit<SanitizedConfig, 'admin' | 'collections' | 'globals' | 'i18n' | ServerOnlyRootProperties>
|
} & Omit<SanitizedConfig, 'admin' | 'collections' | 'globals' | 'i18n' | ServerOnlyRootProperties>
|
||||||
|
|
||||||
export const serverOnlyAdminConfigProperties: readonly Partial<ServerOnlyRootAdminProperties>[] = []
|
export const serverOnlyAdminConfigProperties: readonly Partial<ServerOnlyRootAdminProperties>[] = []
|
||||||
@@ -59,6 +59,7 @@ export const serverOnlyConfigProperties: readonly Partial<ServerOnlyRootProperti
|
|||||||
'secret',
|
'secret',
|
||||||
'hooks',
|
'hooks',
|
||||||
'bin',
|
'bin',
|
||||||
|
'i18n',
|
||||||
'typescript',
|
'typescript',
|
||||||
'cors',
|
'cors',
|
||||||
'csrf',
|
'csrf',
|
||||||
@@ -122,12 +123,6 @@ export const createClientConfig = ({
|
|||||||
importMap,
|
importMap,
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
case 'i18n':
|
|
||||||
clientConfig.i18n = {
|
|
||||||
fallbackLanguage: config.i18n.fallbackLanguage,
|
|
||||||
translations: config.i18n.translations,
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case 'localization':
|
case 'localization':
|
||||||
if (typeof config.localization === 'object' && config.localization) {
|
if (typeof config.localization === 'object' && config.localization) {
|
||||||
clientConfig.localization = {}
|
clientConfig.localization = {}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import type { I18nClient, Language } from '@payloadcms/translations'
|
import type { I18nClient, I18nOptions, Language } from '@payloadcms/translations'
|
||||||
import type {
|
import type {
|
||||||
ClientConfig,
|
ClientConfig,
|
||||||
LanguageOptions,
|
LanguageOptions,
|
||||||
@@ -38,7 +38,7 @@ type Props = {
|
|||||||
readonly children: React.ReactNode
|
readonly children: React.ReactNode
|
||||||
readonly config: ClientConfig
|
readonly config: ClientConfig
|
||||||
readonly dateFNSKey: Language['dateFNSKey']
|
readonly dateFNSKey: Language['dateFNSKey']
|
||||||
readonly fallbackLang: ClientConfig['i18n']['fallbackLanguage']
|
readonly fallbackLang: I18nOptions['fallbackLanguage']
|
||||||
readonly isNavOpen?: boolean
|
readonly isNavOpen?: boolean
|
||||||
readonly languageCode: string
|
readonly languageCode: string
|
||||||
readonly languageOptions: LanguageOptions
|
readonly languageOptions: LanguageOptions
|
||||||
|
|||||||
@@ -4,11 +4,12 @@ import type {
|
|||||||
ClientTranslationKeys,
|
ClientTranslationKeys,
|
||||||
ClientTranslationsObject,
|
ClientTranslationsObject,
|
||||||
I18nClient,
|
I18nClient,
|
||||||
|
I18nOptions,
|
||||||
Language,
|
Language,
|
||||||
TFunction,
|
TFunction,
|
||||||
} from '@payloadcms/translations'
|
} from '@payloadcms/translations'
|
||||||
import type { Locale } from 'date-fns'
|
import type { Locale } from 'date-fns'
|
||||||
import type { ClientConfig, LanguageOptions } from 'payload'
|
import type { LanguageOptions } from 'payload'
|
||||||
|
|
||||||
import { importDateFNSLocale, t } from '@payloadcms/translations'
|
import { importDateFNSLocale, t } from '@payloadcms/translations'
|
||||||
import { enUS } from 'date-fns/locale/en-US'
|
import { enUS } from 'date-fns/locale/en-US'
|
||||||
@@ -47,7 +48,7 @@ const Context = createContext<ContextType<any, any>>({
|
|||||||
type Props = {
|
type Props = {
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
dateFNSKey: Language['dateFNSKey']
|
dateFNSKey: Language['dateFNSKey']
|
||||||
fallbackLang: ClientConfig['i18n']['fallbackLanguage']
|
fallbackLang: I18nOptions['fallbackLanguage']
|
||||||
language: string
|
language: string
|
||||||
languageOptions: LanguageOptions
|
languageOptions: LanguageOptions
|
||||||
switchLanguageServerAction: (lang: string) => Promise<void>
|
switchLanguageServerAction: (lang: string) => Promise<void>
|
||||||
|
|||||||
@@ -1278,6 +1278,18 @@ describe('lexicalMain', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('localization', () => {
|
describe('localization', () => {
|
||||||
|
test('ensure lexical translations from other languages do not get sent to the client', async () => {
|
||||||
|
await navigateToLexicalFields()
|
||||||
|
// Now check if the html contains "Comience a escribir"
|
||||||
|
|
||||||
|
const htmlContent = await page.content()
|
||||||
|
|
||||||
|
// Check if the HTML contains "Comience a escribir"
|
||||||
|
expect(htmlContent).not.toContain('Comience a escribir')
|
||||||
|
expect(htmlContent).not.toContain('Beginne zu tippen oder')
|
||||||
|
expect(htmlContent).not.toContain('Cargando...')
|
||||||
|
expect(htmlContent).toContain('Start typing, or press')
|
||||||
|
})
|
||||||
test.skip('ensure simple localized lexical field works', async () => {
|
test.skip('ensure simple localized lexical field works', async () => {
|
||||||
await navigateToLexicalFields(true, true)
|
await navigateToLexicalFields(true, true)
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user