import formatMessage from 'format-message'; import underscoredCrc32 from 'format-message-generate-id/underscored_crc32'; // Cache translation files const cachedTranslationPromises = {}; const createTranslator = ({ locale, fallback, messages, fallbackMessages, options }) => { const translator = __IN_SERVER__ ? formatMessage.namespace() : formatMessage; translator.setup({ translations: { [locale]: messages, [fallback]: fallbackMessages }, locale: [locale, fallback], generateId: underscoredCrc32, ...options }); return translator; }; /** * Takes a locale, e.g. 'sv-SE' and resolves it to the corresponding key in the translations * @param {string} locale Example: `sv-SE` * @param {object} translations * @return {string} Example: `sv` */ export const getLocaleName = (locale, translations) => { if (!locale) { return null; } if (locale in translations) { return locale; } const lowerCase = locale.toLowerCase(); if (lowerCase in translations) { return lowerCase; } const baseLocale = lowerCase.split(/[_-]/)[0]; if (baseLocale in translations) { return baseLocale; } return null; }; export const getLocaleWithFallback = ({ locale, defaultLocale, translations }) => { const fallback = getLocaleName(defaultLocale, translations); const loc = getLocaleName(locale, translations); if (!fallback) { throw new Error( `Default locale "${defaultLocale}" could not be found in translations` ); } return { locale: loc || fallback, fallback }; }; export const loadLocaleMessages = (locale, translations) => { if (!__IN_SERVER__) { return translations[locale](); } if (!cachedTranslationPromises[locale]) { cachedTranslationPromises[locale] = translations[locale](); } return cachedTranslationPromises[locale]; }; export const setupIntl = async (config) => { if (!config.translations) { throw new Error('No translation data provided to translation setup.'); } if (!config.defaultLocale) { throw new Error('No default locale provided to translation setup.'); } const translations = config.translations; const options = config.options || {}; const { locale, fallback } = getLocaleWithFallback({ locale: config.locale, defaultLocale: config.defaultLocale, translations }); const [messages, fallbackMessages] = await Promise.all([ loadLocaleMessages(locale, translations), loadLocaleMessages(fallback, translations) ]); const translator = createTranslator({ locale, fallback, messages, fallbackMessages, options }); return { locale, translator, fallback }; };