Search code examples
meteoryamli18nextreact-i18next

i18next: Cannot load additional translations (yaml)


I have tried quite a lot to load an additional translation to my app, but somehow it doesn't work. I turned on the debugger, and it says that it's loaded. But I don't see anything translated.

import { Meteor } from 'meteor/meteor';
import { Tracker } from 'meteor/tracker';
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import Backend from 'i18next-http-backend';
import HttpApi from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';
import yaml from 'js-yaml';

import Hosts from '../api/hosts/host';

const defaultLang = 'en';
const allLangs = [defaultLang, 'sv', 'tr'];
const options = {
  allowMultiLoading: true,
  backend: {
    loadPath: '/i18n/{{lng}}/{{ns}}.yml',
    parse: function (data) {
      return yaml.load(data);
    },
  },
  debug: true,
  defaultNS: 'common',
  fallbackLng: defaultLang,
  lng: defaultLang,
  load: 'languageOnly', // we only provide en, de -> no region specific locals like en-US, de-DE
  // have a common namespace used around the full app
  ns: [
    'common',
    'accounts',
    'members',
    'hosts',
    'admin',
    'activities',
    'processes',
    'calendar',
    'resources',
  ],
  preload: allLangs,
  saveMissing: true,
  supportedLngs: allLangs,
  useSuspense: process && !process.release,
};

// for browser use http backend to load translations and browser lng detector
if (process && !process.release) {
  i18n.use(Backend).use(initReactI18next).use(LanguageDetector).use(HttpApi);
}

// initialize if not already initialized
if (!i18n.isInitialized) {
  i18n.init(options);
  // check & set lang for user(logged) or host prefences
  Tracker.autorun(() => {
    let preferedLang = defaultLang;
    if (Meteor.userId()) {
      const handler = Meteor.subscribe('me');
      if (handler.ready()) {
        preferedLang = Meteor.user()?.lang;
      }
    } else {
      const handler = Meteor.subscribe('currentHost');
      if (handler.ready()) {
        preferedLang = Hosts.findOne().settings.lang;
      }
    }
    i18n.changeLanguage(preferedLang);
  });
}

export default i18n;
export { defaultLang };

One thing interesting is that I have sv (Swedish) translation working when I set fallbackLng: allLangs, but Turkish still not... With the fallbackLng: defaultLang set; neither Turkish, nor Swedish comes as options in i18n.languages...

Help appreciated!


Solution

  • It turns out that the problem was due to parsing yaml files.

    In Turkish language, the grammar is often upside down comparing to most Indo-European languages. Therefore the variables noted, for example, as this in English:

    actions:
      toThePage: To the page in {{ hostName }}
    

    would be like this in Turkish:

    actions:
      toThePage: {{ hostName }} sayfasına git
    

    and the problem with the parsing with that was that when the value in yaml file starts with a variable definition, like {{hostName}}, author has to make the whole value field within string quotes for it to work, like:

    actions:
      toThePage: '{{ hostName }} sayfasına git'
    

    So this was the solution to the parsing problem in yaml!