Compare Versions - i18next
npm / i18next / Compare Versions
26.3.0
- feat(types): introduce
ResourceNamespaceMap— a separate mergeable augmentation surface for namespace resource types, designed for monorepos where multiple packages each want to contribute their own namespaces. Previously, every package had to coordinate on a singleCustomTypeOptions.resourcesdeclaration (or fall back to typing dependency namespaces asany) becauseresourcesis a single property of an interface and TypeScript reports TS2717 when two declarations of the same property disagree. The new interface merges naturally acrossdeclare module 'i18next'blocks, so each package can ship its owni18next.d.tsindependently. Per-property merge handles same-namespace contributions from multiple packages, and same-key/different-literal conflicts are silently dropped to avoid poisoningt()overload resolution. Fully backwards-compatible — existingCustomTypeOptions.resourcesaugmentations continue to work, and both surfaces can coexist. Scalar options (defaultNS,returnNull,enableSelector, etc.) still belong onCustomTypeOptions. Thanks @sh3xu (#2434). Fixes #2409.
26.2.0
- feat(types): new
parseInterpolationTypeOption (defaulttrue). When set tofalseinCustomTypeOptions, the type-level extractor stops parsing translation strings for{{variable}}patterns. Required byi18next-icuusers — the default extractor mistakes ICU MessageFormat nested-brace plurals like{count, plural, one {{count} row} other {{count} rows}}for an interpolation block and demands a phantom variable name. The flag is type-only; runtime interpolation is governed byInterpolationOptionsand is unaffected. Fixes i18next-icu#85. - fix(types): expose
enableSelectoronInitOptionssoi18next.init({ enableSelector: 'strict' })typechecks without a module augmentation. The runtime already readsopts?.enableSelectorfrom init options; this lands the matching type declaration next to the other selector-resolution knobs. Acceptsfalse | true | 'optimize' | 'strict'. Thanks @Faithfinder (#2431)
26.1.0
- feat:
enableSelector: 'strict'(TypeOptions + runtime option). Opt-in mode that drops the flattened-primary form fromNsResourceat the type level — every namespace (primary included) is exposed only under its own key on$, uniformly across single- and multi-ns hooks. At runtime, a leading selector path segment matching the scope's namespace list is always rewritten as a namespace prefix, including the primary. Eliminates the silent-miss surface area wheret($ => $.primary.foo)typechecks but doesn't resolve under the default mode (see #2429). Backward-compatible: defaultenableSelector: false | true | 'optimize'behavior is unchanged. Note: strict mode is incompatible with the #2405 pattern (keys whose names match sibling namespaces) — those users should stay on default mode.
26.0.10
- feat:
getFixedTaccepts a fourth optionalfixedOptsargument carryingscopeNs— the full namespace list the boundtwas created for. The selector API usesscopeNsto detect when a path's first segment is a namespace prefix, without changing resolution scope. Resolution still uses the boundns(a single primary string in the typical react-i18next setup), so plaint('key')lookups stay isolated to the primary namespace exactly as before — onlyt($ => $.secondaryNs.foo)selectors now route correctly underuseTranslation([nsA, nsB]). Fixes the runtime side of #2429 for thereact-i18nextdefault-nsModecase. The 4th argument is opt-in: existing 3-arggetFixedT(lng, ns, keyPrefix)callers see no behavior change.
26.0.9
- fix(types): unformatted interpolation values are now typed as
string | number(wasstring). i18next stringifies values at runtime, so requiring callers to wrap numbers inString(...)for plain{{var}}placeholders was unnecessary friction — and could mask the real problem when a non-string value was passed alongside multiple interpolation slots (thet()overload resolution would fall through to the 3-arg form and report a confusing "not assignable to string" error against the options object). Typed format specifiers like{{x, number}},{{x, currency}},{{x, datetime}}, etc. keep their precise types; this only relaxes the no-format default. Thecountvariable remainsnumber-only
26.0.8
- fix(types): restore the pre-v25.10.4
ExistsFunctionshape so plain arrow functions can again be assigned toExistsFunction-typed variables (TypeScript cannot infer type predicates through multi-overload assignment). Directi18next.exists(key)calls still narrowkeytoSelectorKey— the predicate is now declared inline oni18n.exists. Custom wrappers that want the narrowing can type themselves astypeof i18next.exists2425
26.0.7
- fix: when a plural lookup misses, the
missingKeydebug log now shows the actual plural-resolved key (e.g.foo.bar_manyfor Polishcount: 14) instead of the base key — making it obvious which plural category was expected and missing 2423 - chore: drop
@babel/runtimeruntime dependency. The build no longer generates any@babel/runtimeimports, so the package is unused by consumers. Rollup now usesbabelHelpers: 'bundled'so any helpers that are ever needed in the future will be inlined rather than imported externally 2424 - chore: stop emitting
dist/esm/i18next.bundled.js. It was byte-identical todist/esm/i18next.jsbecause no helpers were being imported 2424
26.0.6
Security release — all issues found via an internal audit.
- security: warn when a translation string combines
escapeValue: falsewith interpolated variables inside a$t(key, { ... "{{var}}" ... })nesting-options block. In that narrow combination, attacker-controlled string values containing"can break out of the JSON options literal and inject additional nesting options (e.g. redirectlng/ns). The defaultescapeValue: trueconfiguration is unaffected because HTML-escaping neutralises the quote beforeJSON.parse. See the security note in the Nesting docs for the full pattern and mitigations - security: apply
regexEscapetounescapePrefix/unescapeSuffixon par with the other interpolation delimiters. Prevents ReDoS (catastrophic-backtracking) when a misconfigured delimiter contains regex metacharacters, and fixes silent breakage of the{{- var}}syntax when the delimiter contains characters like(,[,. - security: strip CR/LF/NUL and other C0/C1 control characters from string log arguments to prevent log forging via user-controlled translation keys, language codes, namespaces, or interpolation variable names (CWE-117)
- chore: ignore
.env*and*.pem/*.keyfiles in.gitignore
26.0.5
- fix:
cloneInstance().changeLanguage()no longer fails to update language state when the target language is not yet loaded — a race betweeninit()'s deferredload()and the user'schangeLanguage()could overwriteisLanguageChangingTo, causingsetLngPropsto be skipped 2422
26.0.4
- fix(types): inline formatting options like
{{price, currency(EUR)}}are now correctly resolved to their base format type (e.g.numberforcurrency) instead of falling back tostring2378
26.0.3
- fix(types):
addResourceBundlenow accepts an optional 6thoptionsparameter ({ silent?: boolean; skipCopy?: boolean }) matching the runtime API 2419
26.0.2
- fix(types):
t("key", {} as TOptions)no longer produces a type error — the context constraint now bypasses strict checking whencontextisunknown(e.g. fromTOptions) 2418
26.0.1
- fix: Formatter no longer crashes when
alwaysFormatistrueand no format specifier is present (formatisundefined) - fix: Formatter now returns
undefined/nullvalues as-is instead of producingNaNwhen the value is missing
26.0.0
This is a major breaking release:
Breaking Changes
- Remove deprecated
initImmediateoption — the backward-compatibility mapping frominitImmediatetoinitAsync(introduced in v24) has been removed. UseinitAsyncinstead. - Remove legacy
interpolation.formatfunction — the old monolithic format function (interpolation: { format: (value, format, lng) => ... }) is no longer supported. The built-in Formatter (or a custom Formatter module via.use()) is now always used. Migrate to the new formatting approach usingi18next.services.formatter.add()or.addCached()for custom formatters. - Remove console support notice — the console support notice introduced in v25.8.0 has been removed, along with the
showSupportNoticeoption and all related internal suppression logic (globalThis.__i18next_supportNoticeShown,I18NEXT_NO_SUPPORT_NOTICEenv var). See our blog post for the full story. - Remove
simplifyPluralSuffixoption — this option was unused by the core PluralResolver (which relies entirely onIntl.PluralRules). It only had an effect in the old v1/v2/v3 compatibility layer. The v4 test compatibility layer now defaults totrueinternally. - Remove deprecated
@babel/polyfillfrom devDependencies.
Improvements
- Code modernization across all source files:
- Replace
indexOf() > -1/indexOf() < 0with.includes()(~40+ occurrences) - Replace
indexOf() === 0with.startsWith()where appropriate - Replace
varwithconst,'' + objectwithString(object),.substring()with.slice() - Replace
.apply(observer, [event, ...args])with direct callobserver(event, ...args) - Remove unnecessary
.call(this, ...)in BackendConnector retry logic - Fix
array-callback-returnin LanguageUtilsgetBestMatchFromCodes - Clean up all stale
eslint-disablecomments from source files
- Replace
- EventEmitter: add
once()method for one-time event subscriptions - Memory leak fix: move module-level
checkedLoadedForcache to Translator instance, preventing cross-instance state leakage - TypeScript: fix
BackendModulegeneric parameter naming inconsistency between CJS and ESM type definitions - TypeScript: add
once()method toi18nandResourceStoretype interfaces - ESLint 9: migrate from ESLint 8 (airbnb-base) to ESLint 9 flat config with neostandard
- Vitest 4: upgrade from vitest 3 to vitest 4, migrate workspace files to
test.projectsconfig
25.10.10
- feat: suppress support notice automatically in production environments (
NODE_ENV=production)
25.10.9
- feat(types): export
SelectorParam<Ns, KPrefix>helper type — a stable, readable alternative toParameters<TFunction<Ns>>[0]for typing selector function props 2414
25.10.8
- fix(types): reorder
TFunctionSelectoroverloads soParameters<TFunction>resolves to the general selector signature instead of the brandedSelectorKeytype 2412
25.10.7
- feat(types): support typescript 6 to address https://github.com/i18next/react-i18next/issues/1910
25.10.5
- feat(types): selector functions as
keyPrefixingetFixedTnow provide full type-safe key narrowing — the returnedtfunction is scoped to the prefix subtree 2367
- check also for I18NEXT_NO_SUPPORT_NOTICE env variable
- feat(types):
keyFromSelectoris now type-safe — the selector callback is constrained against your resource definitions, catching invalid keys at compile time. Supports optionalnsandkeyPrefixoptions for non-default namespace/prefix contexts 2364
- fix(types):
FilterKeysnow correctly excludes base keys that have context variants when the provided context doesn't match any of them (e.g. keysomewith variantsome_meis no longer accessible withcontext="one")
- feat(types):
keyFromSelectornow returns a brandedSelectorKeytype thatt()accepts directly, enabling pre-computed and reusable translation keys 2364 - feat: support selector syntax for
keyPrefixingetFixedTand per-call options 2367 - feat(types): interpolation values are now automatically typed based on built-in format specifiers —
{{val, number}}requiresnumber,{{val, datetime}}requiresDate,{{name}}requiresstring, etc. Custom formatters can be typed viainterpolationFormatTypeMapinCustomTypeOptions2378 - fix(types):
FilterKeysin selector mode now preserves non-context, non-plural leaf keys whencontextis provided, fixing incorrect type narrowing when combiningreturnObjects: truewithcontext2398
-
- fix:
getFixedT()selector now resolves namespaces against the effectivensrather than the global init options #2406
- fix:
- fix: selector API namespace resolution regression for single-string
nsand primary namespace in array #2405. Reverts the broad namespace-prefix rewrite from v25.8.15 and replaces it with a targeted fix that only rewrites paths starting with a secondary namespace in a multi-namespace array, matching the type-level contract ofGetSource
- update deps
- fix(types):
on()method now correctly returnsthisinstead ofvoid, matching the runtime behavior and enabling proper method chaining in TypeScript
- fix: getCleanedCode now replaces all underscores
- improve support notice shown logic
- improve support notice shown logic
- type definitions for new transDefaultProps option in react-i18next react-i18next: #1895
- Enhance
cloneInstanceto create a new interpolator if interpolation options are passed in. This will address 2371.
- types: export
InterpolationMap
-
feat:
exists()method now respectsreturnObjectsoption - returnsfalsewhen accessing an object key withreturnObjects: false, enabling detection of object vs string keys 2359Note: This is a potential behavior change. If you were previously calling
exists()withreturnObjects: falseon object keys, those calls will now returnfalseinstead oftrue. This enables developers to detect whether a key points to an object or string value.
- fix last change => for cjs there is just 1 default export, no named exports, fixes 2348
- add new selector API to improve TypeScript IDE performance 2322
- To enable it, set
enableSelector: truein your configuration options - With
enableSelector: "optimize", i18next can now handle translation dictionaries of any size, without affecting IDE performance or build times - To assist with the migration, we've published the following packages:
- To enable it, set
- remove unnecessary debug logs
- warn if legacy
interpolation.formatfunction is still used
- fix options type for
parseMissingKeyHandler
- optimize
changeLanguageto correctly usegetBestMatchFromCodes(string or array) 2299 and improveresolvedLanguageset for non canonical codes
This is a potentially breaking release:
- fix: Interpolation fails with arrays (TypeError) and doesn't work with objects in defaultValue 1829
- optimize fix: Bug Report: Unsafe Behavior in i18n.t Function Leading to Potential Code Execution 2273
- if no Intl api, log error and use dummy rule
- early return and log error, if no Intl api
This is a major breaking release:
- remove support for older environments
- remove old i18next JSON formats
- To convert your existing v3 translations to the v4 format, have a look at i18next-v4-format-converter or this web tool.
- remove support for compatibility to v1 API
- Intl API is mandatory now and will not fallback anymore
- possible compatibility layer for older formats:
test/compatibility/v4/v4Compatibility.js - rename
initImmediatetoinitAsync - fallback to
devlanguage if plural rule not found - remove TypeScript v4 support. TypeScript v5 is now an optional peer dependency
- addresses
➡️ check out the migration guide
- fix utils imports for Deno
- use
Intl.getCanonicalLocalesfunction if available to format language code, like suggested in 2244
- types(TFunction): make return not inferrable and use defaultValue as return when provided 2234
- If backend errors with retry flag, set internal state to 0, so reloadingResources should work 147
- optimize getBestMatchFromCodes for https://github.com/i18next/i18next-browser-languageDetector/issues/281
- optimize: consistent _zero special handling also for defaultValue_zero 2124
- intl plural rule for dev is now en (consistent with v3 compatibility)
- fix: Use Typescript 5 types with Typescript 5+ 2108
- Hint: If you're using TypeScript 4 and you navigate to the type definitions in your code editor, it might be you will see the TypeScript 5 types, but the TS compiler should use the correct types.
- types: fix types for array access
- types: fix for older ts version (context validation only for TS 5)
- types: fix FormatFunction should allow any value inside options parameter
- prevent cosmetic SyntaxError because of non catched error variable
- optimize TypeScript V4 export
- types: CustomInstanceExtenstions
- fix types export for TypeScript v4 in combination with react-i18next
- fix for TypeScript v4 in combination with react-i18next
- fix: consider importing '*.js'
- types: optimize mts
- fix some mjs typings
- types: use unknown to better infer types on nested t functions also for older typescript version 2032
- fix: preload languages also on cimode, if configured also as fallbackLng
- fix: preload languages also on cimode, if configured
- preload languages also on cimode, if configured
- pass correct language for custom i18nFormat
- types: named export for FlatNamespace
- types: export some types for next-i18next
- types: fix typescript imports
- types: Add brand to TFunction type so different namespaces' TFunctions are not treated as compatible 1994
- types for hasLoadedNamespace
- fix utils import (for Deno)
- cloneInstance: introduce
forkResourceStore1974 - types: default argument values for ParseKeys type
- types: export ParseKeys
This is a major breaking release:
-
redesigned TypeScript types 1911 (use TypeScript v5)
-
removed
setDebugfunction in the logger: 1954 -
changed
returnNulldefault tofalse1885 -
drop support for old browsers and Node.js < v12 1948
-
ordinal plural keys are now prefixed with
_ordinalto help translators (non-breaking, bacause of fallback) 1945
➡️ check out the migration guide
- extend hasLoadedNamespace function options to pass optional lng to optimize server side usage of react-i18next
- fix: nested interpolation with data model "replace"
- fix: interpolation with data model "replace"
- types: missing dir function export for typescript
- types: allow als general options as second argument for t function
- types: t function overloads fix (open issue is still calling t with optional options argument)
- types: t function overloads for call with ns option in combination with objects
- types: more t function overloads for call with options argument but without ns value
- types: more overloads for t function
- offer possibility to define a language detector's detect function as promise
- types: ability to pass ns as option instead of prefix i.e.
i18next.t('bar', { ns: 'alternate' });
- dir function executible also without initialization
- named export for dir function
- revert: guess if languageDetector is async if no info provided
- guess if languageDetector is async if no info provided
- extend backend connector to accept also backends with promise / async-await signature
- fix CallbackError type
- Make the translation function fully type-safe 1775
BREAKING: Since this is a major rewrite for TypeScript usage we decided to create a major version. For JavaScript users v22.0.0 is equivalent to 21.10.0
- defaultNS can now also be set to false
- fix: make sure retry logic ends for failed backend reads
- allow overriding keyPrefix option t function returned from getFixedT (does not work for normal t function)
- types: new optional unescape option for react-i18next
- fix: respect pluralSeparator for special _zero handling
- types: fix loaded event result
- fix: loadNamespaces() doesn't keep resolving order when the second request completes before the first one 1785
- fix: regression introduced in v21.6.11, respect
appendNamespaceToMissingKeyforparseMissingKeyHandler1507
- fix: interpolation with $ in values resets nextIndex to wrong position with skipOnVariables 1782
- types: keyPrefix in react options
- fix hasLoadedNamespace when providing inmemory resources and a backend but partialBundledLanguages is not set
- fix formatter for false inline options
- make sure resolvedLanguage is set if lazy loading resources
- make sure key and additionally optional defaultValue are passed to parseMissingKeyHandler function 1445
- fix: respect skipOnVariables option passed in t function also for $t() usage
- fix: respect skipOnVariables option passed in t function
- fix: consistently lowercase new formatter names internally
- types: wait option does not exist anymore for react-i18next
- remove console.log statement
- include version info in generated package.json of esm dist
- do not use options.interpolation reference
- add package.json to exports subpath
- rtl fix for -arab language codes
- bind all i18next functions to this, this way you can for example just use t() instead of i18n.t() 1682
- adds support for formats provided by Intl API (number, currency, datetime, relativedate, list)
- optimize do skip natural language detection also if user provided nsSeparator option is passed via direct options
- optimize Intl api check
- fix Intl.PluralRules fallback
- log error if Intl.PluralRules API is not available
- A new RTL support added for
ckblanguage code
- fix defaultNS regression if translation namespace is defined in ns option, fixes #1658
- fix typescript typo for skipOnVariables
This is a major breaking release:
- introduce new v4 json format (intl plural forms with ordinal support), simplifyPluralSuffix not used anymore
skipOnVariablesby default now is true- automatically detect natural language keys (no need to set nsSeparator or keySeparator to false)
- remove deprecated whitelist features
- introduce new i18next.resolvedLanguage property
➡️ check out the migration guide