react-i18next 16.5.8 → 16.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/TransWithoutContext.d.ts +10 -3
- package/dist/amd/react-i18next.js +69 -19
- package/dist/amd/react-i18next.min.js +1 -1
- package/dist/commonjs/useTranslation.js +6 -2
- package/dist/es/package.json +1 -1
- package/dist/es/useTranslation.js +6 -2
- package/dist/umd/react-i18next.js +69 -19
- package/dist/umd/react-i18next.min.js +1 -1
- package/package.json +20 -20
- package/react-i18next.js +69 -19
- package/react-i18next.min.js +1 -1
- package/src/useTranslation.js +14 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-i18next",
|
|
3
|
-
"version": "16.
|
|
3
|
+
"version": "16.6.0",
|
|
4
4
|
"description": "Internationalization for react done right. Using the i18next i18n ecosystem.",
|
|
5
5
|
"main": "dist/commonjs/index.js",
|
|
6
6
|
"types": "./index.d.mts",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"url": "https://github.com/i18next/react-i18next.git"
|
|
68
68
|
},
|
|
69
69
|
"dependencies": {
|
|
70
|
-
"@babel/runtime": "^7.
|
|
70
|
+
"@babel/runtime": "^7.29.2",
|
|
71
71
|
"html-parse-stringify": "^3.0.1",
|
|
72
72
|
"use-sync-external-store": "^1.6.0"
|
|
73
73
|
},
|
|
@@ -88,17 +88,17 @@
|
|
|
88
88
|
}
|
|
89
89
|
},
|
|
90
90
|
"devDependencies": {
|
|
91
|
-
"@babel/cli": "^7.28.
|
|
92
|
-
"@babel/core": "^7.
|
|
93
|
-
"@babel/eslint-parser": "^7.28.
|
|
91
|
+
"@babel/cli": "^7.28.6",
|
|
92
|
+
"@babel/core": "^7.29.0",
|
|
93
|
+
"@babel/eslint-parser": "^7.28.6",
|
|
94
94
|
"@babel/plugin-proposal-async-generator-functions": "^7.20.7",
|
|
95
95
|
"@babel/plugin-proposal-object-rest-spread": "^7.20.7",
|
|
96
|
-
"@babel/plugin-transform-modules-commonjs": "^7.
|
|
97
|
-
"@babel/plugin-transform-runtime": "^7.
|
|
96
|
+
"@babel/plugin-transform-modules-commonjs": "^7.28.6",
|
|
97
|
+
"@babel/plugin-transform-runtime": "^7.29.0",
|
|
98
98
|
"@babel/polyfill": "^7.12.1",
|
|
99
|
-
"@babel/preset-env": "^7.
|
|
99
|
+
"@babel/preset-env": "^7.29.2",
|
|
100
100
|
"@babel/preset-react": "^7.28.5",
|
|
101
|
-
"@babel/register": "^7.28.
|
|
101
|
+
"@babel/register": "^7.28.6",
|
|
102
102
|
"@rollup/plugin-babel": "^6.1.0",
|
|
103
103
|
"@rollup/plugin-commonjs": "^26.0.3",
|
|
104
104
|
"@rollup/plugin-node-resolve": "^15.3.1",
|
|
@@ -106,9 +106,9 @@
|
|
|
106
106
|
"@rollup/plugin-terser": "0.4.4",
|
|
107
107
|
"@testing-library/dom": "^10.4.1",
|
|
108
108
|
"@testing-library/jest-dom": "^6.9.1",
|
|
109
|
-
"@testing-library/react": "^16.3.
|
|
110
|
-
"@types/jest": "^
|
|
111
|
-
"@types/react": "^19.2.
|
|
109
|
+
"@testing-library/react": "^16.3.2",
|
|
110
|
+
"@types/jest": "^30.0.0",
|
|
111
|
+
"@types/react": "^19.2.14",
|
|
112
112
|
"@vitest/coverage-v8": "^2.0.5",
|
|
113
113
|
"all-contributors-cli": "^6.26.1",
|
|
114
114
|
"babel-core": "^7.0.0-bridge.0",
|
|
@@ -127,15 +127,15 @@
|
|
|
127
127
|
"eslint-plugin-testing-library": "^6.5.0",
|
|
128
128
|
"happy-dom": "^14.12.3",
|
|
129
129
|
"husky": "^9.1.7",
|
|
130
|
-
"i18next": "^25.
|
|
131
|
-
"lint-staged": "^
|
|
130
|
+
"i18next": "^25.10.1",
|
|
131
|
+
"lint-staged": "^16.4.0",
|
|
132
132
|
"mkdirp": "^3.0.1",
|
|
133
|
-
"prettier": "^3.
|
|
134
|
-
"react": "^19.2.
|
|
135
|
-
"react-dom": "^19.2.
|
|
136
|
-
"react-test-renderer": "^19.2.
|
|
137
|
-
"rimraf": "^6.1.
|
|
138
|
-
"rollup": "^4.
|
|
133
|
+
"prettier": "^3.8.1",
|
|
134
|
+
"react": "^19.2.4",
|
|
135
|
+
"react-dom": "^19.2.4",
|
|
136
|
+
"react-test-renderer": "^19.2.4",
|
|
137
|
+
"rimraf": "^6.1.3",
|
|
138
|
+
"rollup": "^4.59.1",
|
|
139
139
|
"typescript": "~5.9.3",
|
|
140
140
|
"vitest": "^2.0.5",
|
|
141
141
|
"yargs": "^17.7.2"
|
package/react-i18next.js
CHANGED
|
@@ -194,7 +194,7 @@
|
|
|
194
194
|
}
|
|
195
195
|
return current;
|
|
196
196
|
};
|
|
197
|
-
const getCleanedCode = code => code?.replace(
|
|
197
|
+
const getCleanedCode = code => code?.replace(/_/g, '-');
|
|
198
198
|
const consoleLogger = {
|
|
199
199
|
type: 'logger',
|
|
200
200
|
log(args) {
|
|
@@ -450,7 +450,16 @@
|
|
|
450
450
|
const {
|
|
451
451
|
[PATH_KEY]: path
|
|
452
452
|
} = selector(createProxy());
|
|
453
|
-
|
|
453
|
+
const keySeparator = opts?.keySeparator ?? '.';
|
|
454
|
+
const nsSeparator = opts?.nsSeparator ?? ':';
|
|
455
|
+
if (path.length > 1 && nsSeparator) {
|
|
456
|
+
const ns = opts?.ns;
|
|
457
|
+
const nsArray = Array.isArray(ns) ? ns : null;
|
|
458
|
+
if (nsArray && nsArray.length > 1 && nsArray.slice(1).includes(path[0])) {
|
|
459
|
+
return `${path[0]}${nsSeparator}${path.slice(1).join(keySeparator)}`;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
return path.join(keySeparator);
|
|
454
463
|
}
|
|
455
464
|
const checkedLoadedFor = {};
|
|
456
465
|
const shouldHandleAsObject = res => !isString$1(res) && typeof res !== 'boolean' && typeof res !== 'number';
|
|
@@ -523,6 +532,10 @@
|
|
|
523
532
|
...opt
|
|
524
533
|
});
|
|
525
534
|
if (!Array.isArray(keys)) keys = [String(keys)];
|
|
535
|
+
keys = keys.map(k => typeof k === 'function' ? keysFromSelector(k, {
|
|
536
|
+
...this.options,
|
|
537
|
+
...opt
|
|
538
|
+
}) : String(k));
|
|
526
539
|
const returnDetails = opt.returnDetails !== undefined ? opt.returnDetails : this.options.returnDetails;
|
|
527
540
|
const keySeparator = opt.keySeparator !== undefined ? opt.keySeparator : this.options.keySeparator;
|
|
528
541
|
const {
|
|
@@ -769,6 +782,10 @@
|
|
|
769
782
|
let usedLng;
|
|
770
783
|
let usedNS;
|
|
771
784
|
if (isString$1(keys)) keys = [keys];
|
|
785
|
+
if (Array.isArray(keys)) keys = keys.map(k => typeof k === 'function' ? keysFromSelector(k, {
|
|
786
|
+
...this.options,
|
|
787
|
+
...opt
|
|
788
|
+
}) : k);
|
|
772
789
|
keys.forEach(k => {
|
|
773
790
|
if (this.isValidLookup(found)) return;
|
|
774
791
|
const extracted = this.extractFromKey(k, opt);
|
|
@@ -1007,9 +1024,6 @@
|
|
|
1007
1024
|
this.logger = baseLogger.create('pluralResolver');
|
|
1008
1025
|
this.pluralRulesCache = {};
|
|
1009
1026
|
}
|
|
1010
|
-
addRule(lng, obj) {
|
|
1011
|
-
this.rules[lng] = obj;
|
|
1012
|
-
}
|
|
1013
1027
|
clearCache() {
|
|
1014
1028
|
this.pluralRulesCache = {};
|
|
1015
1029
|
}
|
|
@@ -1029,7 +1043,7 @@
|
|
|
1029
1043
|
type
|
|
1030
1044
|
});
|
|
1031
1045
|
} catch (err) {
|
|
1032
|
-
if (
|
|
1046
|
+
if (typeof Intl === 'undefined') {
|
|
1033
1047
|
this.logger.error('No Intl support, please use an Intl polyfill!');
|
|
1034
1048
|
return dummyRule;
|
|
1035
1049
|
}
|
|
@@ -1209,13 +1223,13 @@
|
|
|
1209
1223
|
const handleHasOptions = (key, inheritedOptions) => {
|
|
1210
1224
|
const sep = this.nestingOptionsSeparator;
|
|
1211
1225
|
if (key.indexOf(sep) < 0) return key;
|
|
1212
|
-
const c = key.split(new RegExp(`${sep}[ ]*{`));
|
|
1226
|
+
const c = key.split(new RegExp(`${regexEscape(sep)}[ ]*{`));
|
|
1213
1227
|
let optionsString = `{${c[1]}`;
|
|
1214
1228
|
key = c[0];
|
|
1215
1229
|
optionsString = this.interpolate(optionsString, clonedOptions);
|
|
1216
1230
|
const matchedSingleQuotes = optionsString.match(/'/g);
|
|
1217
1231
|
const matchedDoubleQuotes = optionsString.match(/"/g);
|
|
1218
|
-
if ((matchedSingleQuotes?.length ?? 0) % 2 === 0 && !matchedDoubleQuotes || matchedDoubleQuotes
|
|
1232
|
+
if ((matchedSingleQuotes?.length ?? 0) % 2 === 0 && !matchedDoubleQuotes || (matchedDoubleQuotes?.length ?? 0) % 2 !== 0) {
|
|
1219
1233
|
optionsString = optionsString.replace(/'/g, '"');
|
|
1220
1234
|
}
|
|
1221
1235
|
try {
|
|
@@ -1693,6 +1707,23 @@
|
|
|
1693
1707
|
}
|
|
1694
1708
|
});
|
|
1695
1709
|
};
|
|
1710
|
+
const SUPPORT_NOTICE_KEY = '__i18next_supportNoticeShown';
|
|
1711
|
+
const getSupportNoticeShown = () => typeof globalThis !== 'undefined' && !!globalThis[SUPPORT_NOTICE_KEY];
|
|
1712
|
+
const setSupportNoticeShown = () => {
|
|
1713
|
+
if (typeof globalThis !== 'undefined') globalThis[SUPPORT_NOTICE_KEY] = true;
|
|
1714
|
+
};
|
|
1715
|
+
const usesLocize = inst => {
|
|
1716
|
+
if (inst?.modules?.backend?.name?.indexOf('Locize') > 0) return true;
|
|
1717
|
+
if (inst?.modules?.backend?.constructor?.name?.indexOf('Locize') > 0) return true;
|
|
1718
|
+
if (inst?.options?.backend?.backends) {
|
|
1719
|
+
if (inst.options.backend.backends.some(b => b?.name?.indexOf('Locize') > 0 || b?.constructor?.name?.indexOf('Locize') > 0)) return true;
|
|
1720
|
+
}
|
|
1721
|
+
if (inst?.options?.backend?.projectId) return true;
|
|
1722
|
+
if (inst?.options?.backend?.backendOptions) {
|
|
1723
|
+
if (inst.options.backend.backendOptions.some(b => b?.projectId)) return true;
|
|
1724
|
+
}
|
|
1725
|
+
return false;
|
|
1726
|
+
};
|
|
1696
1727
|
class I18n extends EventEmitter {
|
|
1697
1728
|
constructor(options = {}, callback) {
|
|
1698
1729
|
super();
|
|
@@ -1745,6 +1776,10 @@
|
|
|
1745
1776
|
if (typeof this.options.overloadTranslationOptionHandler !== 'function') {
|
|
1746
1777
|
this.options.overloadTranslationOptionHandler = defOpts.overloadTranslationOptionHandler;
|
|
1747
1778
|
}
|
|
1779
|
+
if (this.options.showSupportNotice !== false && !usesLocize(this) && !getSupportNoticeShown()) {
|
|
1780
|
+
if (typeof console !== 'undefined' && typeof console.info !== 'undefined') console.info('🌐 i18next is made possible by our own product, Locize — consider powering your project with managed localization (AI, CDN, integrations): https://locize.com 💙');
|
|
1781
|
+
setSupportNoticeShown();
|
|
1782
|
+
}
|
|
1748
1783
|
const createClassOnDemand = ClassOrObject => {
|
|
1749
1784
|
if (!ClassOrObject) return null;
|
|
1750
1785
|
if (typeof ClassOrObject === 'function') return new ClassOrObject();
|
|
@@ -2005,21 +2040,20 @@
|
|
|
2005
2040
|
o.lngs = o.lngs || fixedT.lngs;
|
|
2006
2041
|
o.ns = o.ns || fixedT.ns;
|
|
2007
2042
|
if (o.keyPrefix !== '') o.keyPrefix = o.keyPrefix || keyPrefix || fixedT.keyPrefix;
|
|
2043
|
+
const selectorOpts = {
|
|
2044
|
+
...this.options,
|
|
2045
|
+
...o
|
|
2046
|
+
};
|
|
2047
|
+
if (typeof o.keyPrefix === 'function') o.keyPrefix = keysFromSelector(o.keyPrefix, selectorOpts);
|
|
2008
2048
|
const keySeparator = this.options.keySeparator || '.';
|
|
2009
2049
|
let resultKey;
|
|
2010
2050
|
if (o.keyPrefix && Array.isArray(key)) {
|
|
2011
2051
|
resultKey = key.map(k => {
|
|
2012
|
-
if (typeof k === 'function') k = keysFromSelector(k,
|
|
2013
|
-
...this.options,
|
|
2014
|
-
...opts
|
|
2015
|
-
});
|
|
2052
|
+
if (typeof k === 'function') k = keysFromSelector(k, selectorOpts);
|
|
2016
2053
|
return `${o.keyPrefix}${keySeparator}${k}`;
|
|
2017
2054
|
});
|
|
2018
2055
|
} else {
|
|
2019
|
-
if (typeof key === 'function') key = keysFromSelector(key,
|
|
2020
|
-
...this.options,
|
|
2021
|
-
...opts
|
|
2022
|
-
});
|
|
2056
|
+
if (typeof key === 'function') key = keysFromSelector(key, selectorOpts);
|
|
2023
2057
|
resultKey = o.keyPrefix ? `${o.keyPrefix}${keySeparator}${key}` : key;
|
|
2024
2058
|
}
|
|
2025
2059
|
return this.t(resultKey, o);
|
|
@@ -2160,7 +2194,19 @@
|
|
|
2160
2194
|
clone.store = new ResourceStore(clonedData, mergedOptions);
|
|
2161
2195
|
clone.services.resourceStore = clone.store;
|
|
2162
2196
|
}
|
|
2163
|
-
if (options.interpolation)
|
|
2197
|
+
if (options.interpolation) {
|
|
2198
|
+
const defOpts = get();
|
|
2199
|
+
const mergedInterpolation = {
|
|
2200
|
+
...defOpts.interpolation,
|
|
2201
|
+
...this.options.interpolation,
|
|
2202
|
+
...options.interpolation
|
|
2203
|
+
};
|
|
2204
|
+
const mergedForInterpolator = {
|
|
2205
|
+
...mergedOptions,
|
|
2206
|
+
interpolation: mergedInterpolation
|
|
2207
|
+
};
|
|
2208
|
+
clone.services.interpolator = new Interpolator(mergedForInterpolator);
|
|
2209
|
+
}
|
|
2164
2210
|
clone.translator = new Translator(clone.services, mergedOptions);
|
|
2165
2211
|
clone.translator.on('*', (event, ...args) => {
|
|
2166
2212
|
clone.emit(event, ...args);
|
|
@@ -3601,8 +3647,12 @@
|
|
|
3601
3647
|
wrapperLangRef.current = lang;
|
|
3602
3648
|
}
|
|
3603
3649
|
}
|
|
3604
|
-
const
|
|
3605
|
-
|
|
3650
|
+
const effectiveT = !ready && !useSuspense ? (...args) => {
|
|
3651
|
+
warnOnce(i18n, 'USE_T_BEFORE_READY', 'useTranslation: t was called before ready. When using useSuspense: false, make sure to check the ready flag before using t.');
|
|
3652
|
+
return t(...args);
|
|
3653
|
+
} : t;
|
|
3654
|
+
const arr = [effectiveT, i18nWrapper, ready];
|
|
3655
|
+
arr.t = effectiveT;
|
|
3606
3656
|
arr.i18n = i18nWrapper;
|
|
3607
3657
|
arr.ready = ready;
|
|
3608
3658
|
return arr;
|