import 'server-only'; import { cookies, headers } from 'next/headers'; import type { I18n, Messages } from '@lingui/core'; import { setupI18n } from '@lingui/core'; import { setI18n } from '@lingui/react/server'; import { IS_APP_WEB } from '../../constants/app'; import { SUPPORTED_LANGUAGE_CODES } from '../../constants/i18n'; import { extractLocaleData } from '../../utils/i18n'; type SupportedLanguages = (typeof SUPPORTED_LANGUAGE_CODES)[number]; async function loadCatalog(lang: SupportedLanguages): Promise<{ [k: string]: Messages; }> { const { messages } = await import( `../../translations/${lang}/${IS_APP_WEB ? 'web' : 'marketing'}.js` ); return { [lang]: messages, }; } const catalogs = await Promise.all(SUPPORTED_LANGUAGE_CODES.map(loadCatalog)); // transform array of catalogs into a single object export const allMessages = catalogs.reduce((acc, oneCatalog) => { return { ...acc, ...oneCatalog }; }, {}); type AllI18nInstances = { [K in SupportedLanguages]: I18n }; // eslint-disable-next-line @typescript-eslint/consistent-type-assertions export const allI18nInstances = SUPPORTED_LANGUAGE_CODES.reduce((acc, lang) => { const messages = allMessages[lang] ?? {}; const i18n = setupI18n({ locale: lang, messages: { [lang]: messages }, }); return { ...acc, [lang]: i18n }; }, {}) as AllI18nInstances; /** * This needs to be run in all layouts and page server components that require i18n. * * https://lingui.dev/tutorials/react-rsc#pages-layouts-and-lingui */ export const setupI18nSSR = () => { const { lang, locales } = extractLocaleData({ cookies: cookies(), headers: headers(), }); // Get and set a ready-made i18n instance for the given language. const i18n = allI18nInstances[lang]; // Reactivate the i18n instance with the locale for date and number formatting. i18n.activate(lang, locales); setI18n(i18n); return { lang, locales, i18n, }; };