Overview
Using react-i18next for existing translations needs. Came across a case to update the translation's values by key at runtime.
Issue
I've tried using https://www.i18next.com/overview/api#addresource addResource in this instance but it _adds_ a new key / value pair to the translations, rather than updates the existing value by key.
Example:
const runTimeTranslationUpdates = {"api.translations.engineTemp": 44.5}
i18next.addResources('en', 'translations', runTimeTranslationUpdates)
Outcome
In this case the translation expected to update by that given key, isn't changed in the render after addResources has been called.
Expected Outcome
addResources updates the existing translation's values by the given key api.translations.engineTemp in runTimeTranslationUpdates object.
Question
Is there an i18next api method to update translation on the fly by key?
I couldn't find an issue similar to this, hence why I've opened a new issue.
This issue is similar but is aimed at adding rather than updating the translations:
https://github.com/i18next/react-i18next/issues/356
https://www.i18next.com/overview/api#addresource -> API is like:
i18next.addResource('en', 'translations', 'api.translations.engineTemp', '44.5')
ah you're using the addResources: https://github.com/i18next/i18next/blob/master/src/ResourceStore.js#L61 should work...but the value needs to be a string.
@jamuhl this is the API function I'm using addResources. But it isn't refreshing the translations.
Should addResources do that or is there another method call needed to trigger the translates again?
I see this line emits the added event after addResources is called:
yes emits the added event on resourceStore -> if bind store has added: https://react.i18next.com/components/withnamespaces#set-defaults-for-all-used-withnamespaces
it should rerender...at least if not set option silent on adding
Turned out the i18nextConfig.ns value is being interpreted
as an array when passed to addResources.
So giving i18next.addResources(lng, i18nextConfig.ns, runTimeData); doesn't work
as i18nextConfig.ns - ["translation"] is an array.
The transformOptions function
does this transform.
Before:
export const i18nextConfig: any = {
lng: "de",
ns: "translation",
resources: {
de: {
translation: {...{data: apiDataDeJson}}
},
en: {
translation: {...{data: apiDataEnJson}}
}
}
};
export const runTimeTranslations = (runTimeData: any, lng: string) => {
i18next.addResources(lng, i18nextConfig.ns, runTimeData);
};
export const i18n: i18next.i18n = i18next.init(i18nextConfig);
After:
Fixed this by passing i18nextConfig.ns[0] as inputOption to i18next.addResources:
Maybe it should be called out in the docs, that ns option is mutated to an array type in init?
export const i18nextConfig: any = {
lng: "de",
ns: ["translation"],
resources: {
de: {
translation: {...{data: apiDataDeJson}}
},
en: {
translation: {...{data: apiDataEnJson}}
}
}
};
export const runTimeTranslations = (runTimeData: any, lng: string) => {
i18next.addResources(lng, i18nextConfig.ns[0], runTimeData);
};
export const i18n: i18next.i18n = i18next.init(i18nextConfig);

could this be closed?
Most helpful comment
Turned out the i18nextConfig.ns value is being interpreted
as an array when passed to addResources.
So giving
i18next.addResources(lng, i18nextConfig.ns, runTimeData);doesn't workas i18nextConfig.ns -
["translation"]is an array.The transformOptions function
does this transform.
Before:
After:
Fixed this by passing i18nextConfig.ns[0] as inputOption to
i18next.addResources:Maybe it should be called out in the docs, that
nsoption is mutated to an array type in init?