So I am using react-intl for the interface, and using TAPi18n-db for content translation. I’m also using moment locales for some calendar stuff.
So I guess this is an example that might be helpful either way. Sorry if this is a lot of code but hopefully you will find something in it that’s helpful @tidee.
From the lang
prop in AppContainer.jsx you can imagine just passing that down as far as you need it.
This is the code of my client/main.js file:
import { Meteor } from 'meteor/meteor';
import { render, unmountComponentAtNode } from 'react-dom';
import moment from 'moment';
import 'moment/locale/es';
import { TAPi18n } from 'meteor/tap:i18n';
import { addLocaleData } from 'react-intl'
import en from 'react-intl/locale-data/en'
import es from 'react-intl/locale-data/es'
import { renderRoutes, loadTranslation } from '../imports/startup/client/routes.jsx';
import '/imports/startup/client';
addLocaleData(en);
addLocaleData(es);
const initiateRender = () => {
window.AppState = {
container: document.getElementById('app'),
getLocale: function() {
return localStorage.getItem('locale') || 'en';
},
setLocale: function(lang) {
localStorage.setItem('locale', lang);
moment.locale(lang);
},
render: function() {
var locale = this.getLocale();
TAPi18n.setLanguage(locale);
moment.locale(locale);
const messages = loadTranslation( { locale });
render(renderRoutes({ locale, messages }), this.container)
},
unmount: function() {
unmountComponentAtNode(this.container);
},
rerender: function() {
this.unmount();
this.render();
}
}
}
Meteor.startup(() => {
const areIntlLocalesSupported = require('intl-locales-supported');
const localesMyAppSupports = [
'en',
'es'
];
if (global.Intl) {
// Determine if the built-in `Intl` has the locale data we need.
if (!areIntlLocalesSupported(localesMyAppSupports)) {
// `Intl` exists, but it doesn't have the data we need, so load the
// polyfill and patch the constructors we need with the polyfill's.
var IntlPolyfill = require('intl');
Intl.NumberFormat = IntlPolyfill.NumberFormat;
Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat;
}
initiateRender();
window.AppState.render();
} else {
// No `Intl`, so use and load the polyfill.
global.Intl = require('intl');
initiateRender();
window.AppState.render();
}
});
Then I have an AppContainer.jsx file:
const AppContainer = createContainer(() => {
// Language
// You could also call TAPi18n.getLanguage() here if you don't want the extra step of all that stuff in main.js
// const lang = TAPi18n.getLanguage();
const lang = window.AppState.getLocale();
const supportedLanguages = TAPi18n.getLanguages();
return {
user: Meteor.user(),
connected: Meteor.status().connected,
menuOpen: Session.get('menuOpen'),
lang,
supportedLanguages,
};
}, App);
export default AppContainer;
Then I have a routes.jsx file:
export const loadTranslation = ({ locale }) => {
let messages = {};
if (locale === 'es') {
messages = require("/i18n/es.json");
}
return messages;
};
export const renderRoutes = ({ locale, messages }) => (
<IntlProvider locale={locale} key={locale} messages={messages}>
<Router>
<Route path="/" component={AppContainer}>
</Routes>
</IntlProvider>
);