diff --git a/packages/next/src/utilities/getRequestLanguage.ts b/packages/next/src/utilities/getRequestLanguage.ts index 7b4a45891ca..2d070e2105f 100644 --- a/packages/next/src/utilities/getRequestLanguage.ts +++ b/packages/next/src/utilities/getRequestLanguage.ts @@ -14,25 +14,24 @@ type GetRequestLanguageArgs = { export const getRequestLanguage = ({ config, cookies, - defaultLanguage = 'en', headers, }: GetRequestLanguageArgs): AcceptedLanguages => { + const supportedLanguageKeys = Object.keys(config.i18n.supportedLanguages) const langCookie = cookies.get(`${config.cookiePrefix || 'payload'}-lng`) - const languageFromCookie = typeof langCookie === 'string' ? langCookie : langCookie?.value + const languageFromCookie: AcceptedLanguages = ( + typeof langCookie === 'string' ? langCookie : langCookie?.value + ) as AcceptedLanguages const languageFromHeader = headers.get('Accept-Language') ? extractHeaderLanguage(headers.get('Accept-Language')) : undefined - const fallbackLang = config?.i18n?.fallbackLanguage || defaultLanguage - - const supportedLanguageKeys = Object.keys(config?.i18n?.supportedLanguages || {}) if (languageFromCookie && supportedLanguageKeys.includes(languageFromCookie)) { - return languageFromCookie as AcceptedLanguages + return languageFromCookie } if (languageFromHeader && supportedLanguageKeys.includes(languageFromHeader)) { return languageFromHeader } - return supportedLanguageKeys.includes(fallbackLang) ? (fallbackLang as AcceptedLanguages) : 'en' + return config.i18n.fallbackLanguage } diff --git a/packages/payload/src/config/defaults.ts b/packages/payload/src/config/defaults.ts index fb522c5ac0a..9fbd1c1cf95 100644 --- a/packages/payload/src/config/defaults.ts +++ b/packages/payload/src/config/defaults.ts @@ -28,6 +28,7 @@ export const defaults: Omit = { maxComplexity: 1000, }, hooks: {}, + i18n: {}, localization: false, maxDepth: 10, routes: { diff --git a/packages/payload/src/config/sanitize.ts b/packages/payload/src/config/sanitize.ts index efc0ec9213f..6ec15f82c88 100644 --- a/packages/payload/src/config/sanitize.ts +++ b/packages/payload/src/config/sanitize.ts @@ -1,3 +1,5 @@ +import type { AcceptedLanguages } from '@payloadcms/translations' + import { en } from '@payloadcms/translations/languages/en' import merge from 'deepmerge' @@ -88,15 +90,29 @@ export const sanitizeConfig = async (incomingConfig: Config): PromiseObject.keys(i18nConfig.supportedLanguages) + const fallbackLang = incomingConfig.i18n?.fallbackLanguage || i18nConfig.fallbackLanguage + + i18nConfig.fallbackLanguage = supportedLangKeys.includes(fallbackLang) + ? fallbackLang + : supportedLangKeys[0] + i18nConfig.translations = incomingConfig.i18n?.translations || i18nConfig.translations + } + + config.i18n = i18nConfig + configWithDefaults.collections.push(getPreferencesCollection(config as unknown as Config)) configWithDefaults.collections.push(migrationsCollection) diff --git a/packages/payload/src/translations/getLocalI18n.ts b/packages/payload/src/translations/getLocalI18n.ts index 93977977512..1da37159524 100644 --- a/packages/payload/src/translations/getLocalI18n.ts +++ b/packages/payload/src/translations/getLocalI18n.ts @@ -6,10 +6,10 @@ import type { SanitizedConfig } from '../config/types.js' export const getLocalI18n = async ({ config, - language = 'en', + language, }: { config: SanitizedConfig - language?: AcceptedLanguages + language: AcceptedLanguages }) => initI18n({ config: config.i18n, diff --git a/packages/payload/src/utilities/createLocalReq.ts b/packages/payload/src/utilities/createLocalReq.ts index 09bfa921eb3..a84480b0c71 100644 --- a/packages/payload/src/utilities/createLocalReq.ts +++ b/packages/payload/src/utilities/createLocalReq.ts @@ -68,8 +68,6 @@ export const createLocalReq: CreateLocalReq = async ( { context, fallbackLocale, locale: localeArg, req = {} as PayloadRequestWithData, user }, payload, ) => { - const i18n = req?.i18n || (await getLocalI18n({ config: payload.config })) - if (payload.config?.localization) { const locale = localeArg === '*' ? 'all' : localeArg const defaultLocale = payload.config.localization.defaultLocale @@ -84,6 +82,10 @@ export const createLocalReq: CreateLocalReq = async ( } } + const i18n = + req?.i18n || + (await getLocalI18n({ config: payload.config, language: payload.config.i18n.fallbackLanguage })) + // @ts-expect-error if (!req.headers) req.headers = new Headers() req.context = getRequestContext(req, context) diff --git a/packages/translations/src/types.ts b/packages/translations/src/types.ts index 2a8fdd54ebd..117876edf39 100644 --- a/packages/translations/src/types.ts +++ b/packages/translations/src/types.ts @@ -63,7 +63,7 @@ export type I18n = { } export type I18nOptions = { - fallbackLanguage?: string + fallbackLanguage?: AcceptedLanguages supportedLanguages?: SupportedLanguages translations?: Partial<{ [key in AcceptedLanguages]?: Language['translations'] @@ -82,7 +82,7 @@ export type InitTFunction = (args: { export type InitI18n = (args: { config: I18nOptions context: 'api' | 'client' - language?: AcceptedLanguages + language: AcceptedLanguages }) => Promise export type LanguagePreference = { diff --git a/packages/translations/src/utilities/init.ts b/packages/translations/src/utilities/init.ts index 5d84dbd2146..1a7edd9bbbd 100644 --- a/packages/translations/src/utilities/init.ts +++ b/packages/translations/src/utilities/init.ts @@ -164,7 +164,7 @@ function memoize(fn: (args: unknown) => Promise, keys: string[]) { } export const initI18n: InitI18n = memoize( - async ({ config, context, language = 'en' }: Parameters[0]) => { + async ({ config, context, language = config.fallbackLanguage }: Parameters[0]) => { const translations = getTranslationsByContext(config.supportedLanguages[language], context) const { t, translations: mergedTranslations } = initTFunction({