todos-contra-el-fuego-web/imports/startup/client/i18n.js
vjrj 12bdbe8fed deps: i18next 10 -> 23, react-i18next 7 -> 14
Modernizes the whole i18n stack:
- 48 translate([], {wait:true}) / translate() HOCs -> withTranslation()
- react.wait:true -> react.useSuspense:false
- whitelist -> supportedLngs; added compatibilityJSON: 'v3' so our
  natural-language keys + v3 _plural layout keep working (custom
  separators ss/eth/dj preserved)
- backends: xhr -> i18next-http-backend (client), sync-fs ->
  i18next-fs-backend (server); dropped i18next-localstorage-cache
  (was enabled:false); languagedetector 2 -> 8
- ReSendEmail: <Interpolate> (removed in v10) -> <Trans values={{email}}/>,
  dropped the removed bare t export
- saveMissing handler signature (lngs, ns, key, fallbackValue)

Silences the per-component Translate/I18n legacy-context warnings.
Browser-verified es/en switch and <Trans> interpolation on /fires;
REST smoke byte-identical.
2026-07-18 06:28:41 +02:00

111 lines
3.4 KiB
JavaScript

/* global Intl */
import i18n from 'i18next';
import { Meteor } from 'meteor/meteor';
import { Tracker } from 'meteor/tracker';
import { ReactiveVar } from 'meteor/reactive-var';
import backend from 'i18next-http-backend';
import LngDetector from 'i18next-browser-languagedetector';
import { T9n } from 'meteor-accounts-t9n';
import moment from 'moment';
import 'moment/locale/es';
import 'moment/locale/pt';
import 'moment/locale/gl';
import i18nOpts from '../common/i18n';
// Adapted from: https://github.com/appigram/ryfma-boilerplate/blob/44c1eabfb9928b5623afab36a23997969e5beb02/imports/startup/client/i18n.js
const detectorOptions = {
// order and from where user language should be detected
order: ['querystring', 'navigator', 'cookie', 'localStorage', 'htmlTag'],
// keys or params to lookup language from
lookupQuerystring: 'lng',
lookupCookie: 'i18next',
lookupLocalStorage: 'i18nextLng',
// cache user language on
caches: ['localStorage', 'cookie'],
excludeCacheFor: ['cimode'] // languages to not persist (cookie, localStorage)
};
export const i18nReady = new ReactiveVar(false);
i18nOpts.detection = detectorOptions;
i18nOpts.react = {
useSuspense: false, // was `wait: true` pre-react-i18next-10
defaultTransParent: 'span'
// https://react.i18next.com/components/i18next-instance.ht
/* bindI18n: 'languageChanged loaded',
bindStore: 'added removed',
nsMode: 'default' */
};
const sendMissing = true; // Meteor.isDevelopment;
if (sendMissing && Meteor.isDevelopment) {
i18nOpts.saveMissing = true;
// Modern signature is (lngs, ns, key, fallbackValue, ...); key/fallback keep
// the same positions, so we still only need those two.
i18nOpts.missingKeyHandler = function miss(lngs, ns, key, defaultValue) {
Meteor.call('utility.saveMissingI18n', key, defaultValue);
};
}
function setT9(lang) {
if (lang === 'gl') {
T9n.setLanguage('es');
} else {
T9n.setLanguage(lang);
}
}
i18n.use(backend)
.use(LngDetector)
.init(i18nOpts, (err, t) => {
// initialized and ready to
if (err) {
console.error(err);
return;
}
console.log(`Language initialized: ${i18n.language}`);
// document.title = t('AppName');
// Accounts translation
// https://github.com/softwarerero/meteor-accounts-t9n
setT9(i18n.language);
// console.log(T9n.get('error.accounts.User not found'));
moment.locale(i18n.language);
i18nReady.set(true);
// Cookie consent banner: selaias:cookie-consent (Blaze, dead on Meteor 3)
// replaced by the React component imports/ui/components/CookieConsent,
// which reuses the same i18n keys.
});
Meteor.subscribe('userData'); // lang is there
i18n.on('languageChanged', (lng) => {
moment.locale(lng);
// TODO fix this when gl is translated
setT9(lng);
Tracker.autorun((computation) => {
if (Meteor.userId()) {
// logged
if (Meteor.user() && (typeof Meteor.user().lang === 'undefined' ||
Meteor.user().lang !== lng)
) {
// Set the autodetected/changed lang
console.log(`Setting the autodetected lang ${lng}, from previous ${Meteor.user().lang}`);
// console.log(Meteor.user());
Meteor.call('users.setLang', lng, (error) => {
if (error) {
console.error(error);
}
});
computation.stop(); // not need it again til new lang change
}
}
});
});
export default i18n;