Open louy2 opened 8 years ago
Hi @louy2, I got a new job this week and I am adapting, I will continue figure this feature soon, thx for your attention :dog:
@louy2 I got it working with react intl v2. Some tips:
@halt-hammerzeit So each component defines messages it needs and the actual messages are still defined elsewhere. What do you think about define once and use anywhere?
@louy2 Each component defines messages and those are what are gonna be the labels in English (=default). Then you create separate bulk translation files for other languages.
A major pain-point we faced at Yahoo which every app experienced
was not wanting to wait for new translations to be finished before deploying,
or placeholders like {name} getting translated to {nombre} accidentally.
https://github.com/yahoo/react-intl/issues/162 "Default Message Declaration and Extraction"
Whatever
@halt-hammerzeit this is nearly exactly what I have done in my project today with React Intl v2. I took a different direction with the polyfills, following more closely the examples found on Intl.js and Format.JS website:
const component = (
<IntlProvider locale={store.yaddayadda} messages={{ /* stuff from your store */}} >
<ReduxRouter routes={getRoutes(store)} />
</IntlProvider>
);
if (!window.Intl) {
require.ensure([
'intl',
'intl/locale-data/jsonp/en.js',
'intl/locale-data/jsonp/es.js',
'intl/locale-data/jsonp/fr.js',
'intl/locale-data/jsonp/de.js',
'intl/locale-data/jsonp/it.js',
'intl/locale-data/jsonp/ja.js',
], (require) => {
require('intl');
require('intl/locale-data/jsonp/en.js');
require('intl/locale-data/jsonp/es.js');
require('intl/locale-data/jsonp/fr.js');
require('intl/locale-data/jsonp/de.js');
require('intl/locale-data/jsonp/it.js');
require('intl/locale-data/jsonp/ja.js');
renderApp();
});
} else {
renderApp();
}
function renderApp() {
ReactDOM.render(
<Provider store={store}>
{component}
</Provider>,
dest
);
Hi all, so given that 3 or 4 contributors suggested an implementation for i18n in the project What keeps the moderator from integrating one of them? This is a meaningfull and essential feature.
+1
How can we promote this subject? Months go by and existing PRs are not being integrated. Can anyone point on the reason for this critical feature not integrated yet??? we can +1 for months without any response or check out other implementations like http://mern.io/ that do include i18n support out of the box... What are your thoughts?
Well it is understandable IMO. If the author doesn't use the i18n personally, then he would have little interest in adding and maintaining it. It is common in open source. Using a fork listed above or some alternatives is perfectly fine IMO. Exercise your freedom.
This i18n example repo
https://github.com/simpleblack/react-redux-universal-hot-example
@simpleblack , how to switch between langs on client / server depends on params in url ?
@Iuriy-Budnikov I load my messages into redux based on the url I read the lang from query string and it stays in that language ping me if you need more examples. https://hk.housemeerkat.com/ at the bottom.
It's not optimal for big sites cause I load all the messages once but you can split it per page.
here is what I do:
setLocale.js (express app that sets my locale either from url or query string):
import config from '../config';
const setLocale = (req, res, next) => {
const currentCountry = req.hostname.split('.')[0];
const countryConfig = config.countries[currentCountry] || config.countries.default
const countryLocales = countryConfig.locales;
if (countryLocales != null) {
req.locale = countryLocales[0];
}
// Locale can be changed by passing ?hl=<locale> in the querystring
if (req.query.hl) {
// But only the supported ones!
if (countryLocales.indexOf(req.query.hl) > -1) {
req.locale = req.query.hl;
}
}
// Or by setting a `hl` cookie
else if (req.cookies.hl) {
if (countryLocales.indexOf(req.cookies.hl) > -1) {
req.locale = req.cookies.hl;
}
}
next();
};
export default setLocale;
in server.js
store.dispatch(loadIntlMessages(locale, country));
and this is the reducer:
const LOAD_INTL_SERVER = 'intl/LOAD_INTL_SERVER';
const initialState = {
currentLocale: 'en-AU',
country: 'AU',
messages: {},
};
export default function select(state = initialState, action = {}) {
switch (action.type) {
case LOAD_INTL_SERVER:
return {
...state,
messages: action.messages,
currentLocale: action.locale,
country: action.country,
};
default:
return state;
}
}
export function loadIntlMessages(locale, country) {
const messages = require(`../../../build/lang/${locale}.json`);
return {
type: LOAD_INTL_SERVER,
country: country,
locale: locale,
messages: messages
};
}
it is only ever called once on the server but can be extended to load json dynamically on each page load.
basically in code I use defineMessage and I extract the messages with webpack react intl and put them in files.
I'm happy to help if you have any more queries.
Regards. Andrei
@andreimc thanks for quick response. I found some quick solutions with example @simpleblack
Here my code. Maybe it will helps somebody
i18n-server.js
import i18n from 'i18next';
import Backend from 'i18next-node-fs-backend';
import { LanguageDetector } from 'i18next-express-middleware';
i18n
.use(Backend)
.use(LanguageDetector)
.init({
detection: {
order: ['querystring', 'cookie', 'header'],
// keys or params to lookup language from
lookupQuerystring: 'lang',
lookupCookie: 'i18next',
// cache user language
caches: false // ['cookie']
},
whitelist: ['en', 'ar'],
fallbackLng: 'en',
// have a common namespace used around the full app
ns: ['common'],
defaultNS: 'common',
debug: true,
interpolation: {
escapeValue: false // not needed for react!!
},
backend: {
loadPath: 'locales/{{lng}}/{{ns}}.json',
jsonIndent: 2
}
});
export default i18n;
i18n-client.js
import i18n from 'i18next';
import { LanguageDetector } from 'i18next-express-middleware';
i18n
.use(LanguageDetector)
.init({
detection: {
order: ['querystring', 'cookie', 'header'],
// keys or params to lookup language from
lookupQuerystring: 'lang',
lookupCookie: 'i18next',
// cache user language
caches: false // ['cookie']
// optional expire and domain for set cookie
},
whitelist: ['en', 'ar'],
fallbackLng: 'en',
// have a common namespace used around the full app
ns: ['common'],
defaultNS: 'common',
interpolation: {
escapeValue: false // not needed for react!!
}
});
export default i18n;
Internet is international so I think a good framework cannot go far without i18n (or because I myself am bilingual but whatever). People has done great job on this and I'd like to refer to those with respect:
140 by @halt-hammerzeit
278 by @hank7444 and @lemonCMS
361 by @hank7444 , and hope he is all and well
This issue hope to track further progress and discussion on the issue.