diff --git a/client/lib/i18n.js b/client/lib/i18n.js index 5d809c17b..2e3dd10a4 100644 --- a/client/lib/i18n.js +++ b/client/lib/i18n.js @@ -16,6 +16,15 @@ Meteor.startup(() => { navigator.userLanguage, ].filter(Boolean); if (language) { - TAPi18n.setLanguage(language); + // Try with potentially complex language tag + if (TAPi18n.isLanguageSupported(language)) { + TAPi18n.setLanguage(language); + } else if (language.includes('-')) { + // Fallback to a general language + const [general] = language.split('-'); + if (TAPi18n.isLanguageSupported(general)) { + TAPi18n.setLanguage(general); + } + } } }); diff --git a/imports/i18n/i18n.test.js b/imports/i18n/i18n.test.js index 7805dbdc8..197a1ac19 100644 --- a/imports/i18n/i18n.test.js +++ b/imports/i18n/i18n.test.js @@ -78,8 +78,8 @@ describe('TAPi18n', () => { expect(TAPi18n.i18n.addResourceBundle.firstCall.args[2]).to.have.property('accept'); }); - it('does nothing if language is missing', async () => { - await expect(TAPi18n.loadLanguage('miss')).to.be.fulfilled; + it('throws error if language is missing', async () => { + await expect(TAPi18n.loadLanguage('miss')).to.be.rejectedWith('not supported'); expect(TAPi18n.i18n.addResourceBundle).to.not.be.called; }); diff --git a/imports/i18n/tap.js b/imports/i18n/tap.js index 2916278de..f531a23ae 100644 --- a/imports/i18n/tap.js +++ b/imports/i18n/tap.js @@ -32,6 +32,9 @@ export const TAPi18n = { // Load the current language data await TAPi18n.loadLanguage(DEFAULT_LANGUAGE); }, + isLanguageSupported(language) { + return Object.values(languages).some(({ tag }) => tag === language); + }, getSupportedLanguages() { return Object.values(languages).map(({ name, code, tag }) => ({ name, code, tag })); }, @@ -42,6 +45,8 @@ export const TAPi18n = { if (language in languages && 'load' in languages[language]) { const data = await languages[language].load(); this.i18n.addResourceBundle(language, DEFAULT_NAMESPACE, data); + } else { + throw new Error(`Language ${language} is not supported`); } }, async setLanguage(language) {