i18next / i18next-xhr-backend

[deprecated] can be replaced with i18next-http-backend
https://github.com/i18next/i18next-http-backend
MIT License
253 stars 75 forks source link

How to enable lazy loading of a namespace? #309

Open tonix-tuft opened 5 years ago

tonix-tuft commented 5 years ago

Hi,

I have configured i18next this way using the backend plugin:

i18n
    .use(initReactI18next)
    .use(i18nextXHRBackend)
    .use(intervalPlural)
    .init({
        ...
        ns: ['common'],
        defaultNS: 'common',
        ...
        backend: {
            loadPath: loadPathBaseUrl + '/i18n/res/{{lng}}/{{ns}}.json',

            ajax: backendAJAX,

            // Questa funzione dummy serve (possibile bug di i18next, vedere https://github.com/i18next/i18next-xhr-backend/issues/308)
            parse: (data) => data,

            crossDomain: true
        },
        ...

The backend plugin loads the common namespace initially right after the page is ready, but I also have created a chat namespace file which I would like to load lazily.

If I call t('chat:key') in my code, i18next doesn't load the chat namespace file and the string is not translated.

I can of course add chat to ns like this:

     ...
    .init({
        ...
        ns: ['common', 'chat'], // <---- Explicitly added the namespace
        defaultNS: 'common',
        ...
    ...

But then i18next loads the chat namespace together with the common namespace right after the page loads, and I do not want it because I would like to load chat only if there's at least one call to t with that namespace in the page (i.e. lazy load), e.g. when I call t('chat:key') it would be great if i18next internally checked whether it has already loaded the chat namespace or not, and if it hasn't, load it through the backend plugin.

Is there a way to achieve that?

jamuhl commented 5 years ago

no...it's an implementation detail of the choosen UI framework -> eg. for react react-i18next takes care for loading them before accessing.

makes no sense to try loading them after calling t('chat:key') as at that point you already rendered the missing key value -> so lazy loading needs to happen before -> which obviously is totally out of our control (i18next.loadNamespace can be used in userland)

tonix-tuft commented 5 years ago

Therefore, the only solution is to make i18next load everything initially with this configuration:

     ...
    .init({
        ...
        ns: ['common', 'chat'], // <---- Explicitly added the namespace
        defaultNS: 'common',
        ...
    ...

Right?

And everytime I introduce a new namespace, I just append it to the ns array (e.g.: ns: ['common', 'chat', 'new123']), correct?

jamuhl commented 5 years ago

That's just not lazy loading...like said...load them on demand with i18next.loadNamespaces - like eg. https://github.com/i18next/react-i18next/blob/master/src/useTranslation.js#L90