npm i18next 26.3.5
v26.3.5

2 hours ago
  • fix: $t() nesting options blocks that span multiple lines are now parsed. nest() decided where the nested key ends by testing match[1] with /{.*}/, whose dot does not cross line breaks — so a $t(key, { ... }) options object containing a newline was treated as having no options, mis-split as formatters, and the nested lookup ran without its options (placeholders stayed unresolved). The nesting regexp itself already matches newlines inside $t(...); adding the s (dotAll) flag makes multiline options behave like the single-line form. Thanks @spokodev (#2440).
  • fix: getUsedParamsDetails (the returnDetails: true path) no longer mutates the passed replace object. It wrote count straight onto options.replace so the returned usedParams would include it — a caller reusing one replace object across t() calls then carried a stale count into later interpolations (e.g. a previous call's count: 5 rendered instead of the current call's value). The details are now built from a copy; usedParams still includes count. Thanks @spokodev (#2441).
  • fix: with the default skipOnVariables: true + escapeValue: true, a {{placeholder}} carried inside an interpolated value now stays literal even when the value contains escapable characters. The skip logic advanced the regex lastIndex by the raw value length, but the escaped text written into the string is longer, so lastIndex landed inside the inserted value and a trailing {{placeholder}} in it got interpolated — leaking another in-scope variable that should have stayed literal (values without escapable characters were already skipped correctly). The advance now uses the escaped length that is actually written, and the regex-safe $-doubling is applied only at the String.replace call so it can't distort the length arithmetic. Thanks @spokodev (#2442).

Don't miss a new i18next release

NewReleases is sending notifications on new releases.