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

Load translations form backend even if they are loaded from resources #336

Closed kgonia closed 1 year ago

kgonia commented 4 years ago

Hi,

Is it possible lo load translations form backend even if they are already in resources? My use case is like this: I have default translations in app code but I want to load newer if they are available on the server.

I found out that i18next-xhr-backend don't make call for translations if they are already provided. Is it possible to change this behavior?

jamuhl commented 4 years ago

there is i18next.reloadResources() https://www.i18next.com/overview/api#reloadresources to enforce a fresh loading...

kgonia commented 4 years ago

It enforces a fresh loading (making REST call) but new translations don't show up because components are already rendered.

Calling i18n.changeLanguage() enforces app to show newly loaded translations but this action is called by user...

What am I missing?

jamuhl commented 4 years ago

Nothing...reload does not enforce a rerender (in case of react-i18next)...

you can enforce rerender by binding a custom event like we did for locize-editor changes:

emit like: https://github.com/i18next/react-i18next/blob/master/example/locize/src/i18n.js#L59 bind like: https://github.com/i18next/react-i18next/blob/master/example/locize/src/i18n.js#L63

kgonia commented 4 years ago

I found a trick to achieve my goal. I init with an empty resources, configure backend and call method addResourceBundle with resources that are in a project. It works as expected (use local resources if the server with translations isn't available) but maybe is it a nicer way of doing that?

This is my config:

import i18n from "i18next";
import {initReactI18next} from "react-i18next";
import enlang from './en.json';
import delang from './de.json';
import backend from 'i18next-xhr-backend';

const resources = {
    en: {
        translation: enlang
    },
    de: {
        translation: delang
    }
};
console.log(resources)

i18n
    .use(initReactI18next) // passes i18n down to react-i18next
    .use(backend)
    .init({
        resources: {},
        lng: "en",
        fallbackLng: "de",
        keySeparator: false, 
        interpolation: {
            escapeValue: false
        },
        backend: {
            loadPath: 'http://some_url_to_server/translations?locale={{lng}}&bundles=o',
            crossDomain: true,
            withCredentials: false,
        },
        partialBundledLanguages: true
    });

i18n.addResourceBundle('en', 'translation', enlang);
i18n.addResourceBundle('de', 'translation', delang);

export default i18n;
jamuhl commented 4 years ago

Looks like some lucky timing...depending on what gets done first (load triggered or resources added).

I would either check the init callback or Promise for errors or add local resources on https://www.i18next.com/overview/api#onfailedloading

kgonia commented 4 years ago

@jamuhl Thanks for help! onfailedloading looks safer, more efficient and it works!

jamuhl commented 4 years ago

If you like this module don’t forget to star this repo. Make a tweet, share the word or have a look at our https://locize.com to support the devs of this project.

If you liked my support / work - I would enjoy a coffee sponsored using the “:purple_heart:Sponsor Button”.

There are many ways to help this project :pray: