Update dependency i18next to v26 #554

Open
Renovate wants to merge 1 commit from renovate/i18next-26.x into main
Collaborator

This PR contains the following updates:

Package Type Update Change
i18next (source) dependencies major ^25.3.2^26.0.0

Release Notes

i18next/i18next (i18next)

v26.3.1

Compare Source

  • fix(types): t() with a keyPrefix no longer pollutes its return type with sibling keys' values. A regression in 26.3.0 — the [Res] extends [never] guards added to KeysBuilderWithReturnObjects / KeysBuilderWithoutReturnObjects turned the builders into deferred conditional types, so KeyPrefix<Ns> stopped resolving to a literal union and keyPrefix inference widened to the whole namespace. Symptom: useTranslation(ns, { keyPrefix: 'a.b' }) then t('title') would resolve to '<a.b>.title' | '<other.path>.title' | ... instead of just the scoped value. Affected every react-i18next user using keyPrefix. Restored to the eager 26.2.0 form. The same-namespace conflict handling from #​2434 still works via _DropConflictKeys at the merge layer (in options.d.ts). Thanks @​aaronrosenthal (#​2436).

v26.3.0

Compare Source

  • 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 single CustomTypeOptions.resources declaration (or fall back to typing dependency namespaces as any) because resources is a single property of an interface and TypeScript reports TS2717 when two declarations of the same property disagree. The new interface merges naturally across declare module 'i18next' blocks, so each package can ship its own i18next.d.ts independently. Per-property merge handles same-namespace contributions from multiple packages, and same-key/different-literal conflicts are silently dropped to avoid poisoning t() overload resolution. Fully backwards-compatible — existing CustomTypeOptions.resources augmentations continue to work, and both surfaces can coexist. Scalar options (defaultNS, returnNull, enableSelector, etc.) still belong on CustomTypeOptions. Thanks @​sh3xu (#​2434). Fixes #​2409.

v26.2.0

Compare Source

  • feat(types): new parseInterpolation TypeOption (default true). When set to false in CustomTypeOptions, the type-level extractor stops parsing translation strings for {{variable}} patterns. Required by i18next-icu users — 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 by InterpolationOptions and is unaffected. Fixes i18next-icu#85.
  • fix(types): expose enableSelector on InitOptions so i18next.init({ enableSelector: 'strict' }) typechecks without a module augmentation. The runtime already reads opts?.enableSelector from init options; this lands the matching type declaration next to the other selector-resolution knobs. Accepts false | true | 'optimize' | 'strict'. Thanks @​Faithfinder (#​2431)

v26.1.0

Compare Source

  • feat: enableSelector: 'strict' (TypeOptions + runtime option). Opt-in mode that drops the flattened-primary form from NsResource at 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 where t($ => $.primary.foo) typechecks but doesn't resolve under the default mode (see #​2429). Backward-compatible: default enableSelector: 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.

v26.0.10

Compare Source

  • feat: getFixedT accepts a fourth optional fixedOpts argument carrying scopeNs — the full namespace list the bound t was created for. The selector API uses scopeNs to detect when a path's first segment is a namespace prefix, without changing resolution scope. Resolution still uses the bound ns (a single primary string in the typical react-i18next setup), so plain t('key') lookups stay isolated to the primary namespace exactly as before — only t($ => $.secondaryNs.foo) selectors now route correctly under useTranslation([nsA, nsB]). Fixes the runtime side of #​2429 for the react-i18next default-nsMode case. The 4th argument is opt-in: existing 3-arg getFixedT(lng, ns, keyPrefix) callers see no behavior change.

v26.0.9

Compare Source

  • fix(types): unformatted interpolation values are now typed as string | number (was string). i18next stringifies values at runtime, so requiring callers to wrap numbers in String(...) for plain {{var}} placeholders was unnecessary friction — and could mask the real problem when a non-string value was passed alongside multiple interpolation slots (the t() 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. The count variable remains number-only

v26.0.8

Compare Source

  • fix(types): restore the pre-v25.10.4 ExistsFunction shape so plain arrow functions can again be assigned to ExistsFunction-typed variables (TypeScript cannot infer type predicates through multi-overload assignment). Direct i18next.exists(key) calls still narrow key to SelectorKey — the predicate is now declared inline on i18n.exists. Custom wrappers that want the narrowing can type themselves as typeof i18next.exists 2425

v26.0.7

Compare Source

  • fix: when a plural lookup misses, the missingKey debug log now shows the actual plural-resolved key (e.g. foo.bar_many for Polish count: 14) instead of the base key — making it obvious which plural category was expected and missing 2423
  • chore: drop @babel/runtime runtime dependency. The build no longer generates any @babel/runtime imports, so the package is unused by consumers. Rollup now uses babelHelpers: '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 to dist/esm/i18next.js because no helpers were being imported 2424

v26.0.6

Compare Source

Security release — all issues found via an internal audit.

  • security: warn when a translation string combines escapeValue: false with 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. redirect lng/ns). The default escapeValue: true configuration is unaffected because HTML-escaping neutralises the quote before JSON.parse. See the security note in the Nesting docs for the full pattern and mitigations
  • security: apply regexEscape to unescapePrefix / unescapeSuffix on 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/*.key files in .gitignore

v26.0.5

Compare Source

  • fix: cloneInstance().changeLanguage() no longer fails to update language state when the target language is not yet loaded — a race between init()'s deferred load() and the user's changeLanguage() could overwrite isLanguageChangingTo, causing setLngProps to be skipped 2422

v26.0.4

Compare Source

  • fix(types): inline formatting options like {{price, currency(EUR)}} are now correctly resolved to their base format type (e.g. number for currency) instead of falling back to string 2378

v26.0.3

Compare Source

  • fix(types): addResourceBundle now accepts an optional 6th options parameter ({ silent?: boolean; skipCopy?: boolean }) matching the runtime API 2419

v26.0.2

Compare Source

  • fix(types): t("key", {} as TOptions) no longer produces a type error — the context constraint now bypasses strict checking when context is unknown (e.g. from TOptions) 2418

v26.0.1

Compare Source

  • feat: getFixedT accepts a fourth optional fixedOpts argument carrying scopeNs — the full namespace list the bound t was created for. The selector API uses scopeNs to detect when a path's first segment is a namespace prefix, without changing resolution scope. Resolution still uses the bound ns (a single primary string in the typical react-i18next setup), so plain t('key') lookups stay isolated to the primary namespace exactly as before — only t($ => $.secondaryNs.foo) selectors now route correctly under useTranslation([nsA, nsB]). Fixes the runtime side of #​2429 for the react-i18next default-nsMode case. The 4th argument is opt-in: existing 3-arg getFixedT(lng, ns, keyPrefix) callers see no behavior change.

v26.0.0

Compare Source

This is a major breaking release:

Breaking Changes
  • Remove deprecated initImmediate option — the backward-compatibility mapping from initImmediate to initAsync (introduced in v24) has been removed. Use initAsync instead.
  • Remove legacy interpolation.format function — 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 using i18next.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 showSupportNotice option and all related internal suppression logic (globalThis.__i18next_supportNoticeShown, I18NEXT_NO_SUPPORT_NOTICE env var). See our blog post for the full story.
  • Remove simplifyPluralSuffix option — this option was unused by the core PluralResolver (which relies entirely on Intl.PluralRules). It only had an effect in the old v1/v2/v3 compatibility layer. The v4 test compatibility layer now defaults to true internally.
  • Remove deprecated @babel/polyfill from devDependencies.
Improvements
  • Code modernization across all source files:
    • Replace indexOf() > -1 / indexOf() < 0 with .includes() (~40+ occurrences)
    • Replace indexOf() === 0 with .startsWith() where appropriate
    • Replace var with const, '' + object with String(object), .substring() with .slice()
    • Replace .apply(observer, [event, ...args]) with direct call observer(event, ...args)
    • Remove unnecessary .call(this, ...) in BackendConnector retry logic
    • Fix array-callback-return in LanguageUtils getBestMatchFromCodes
    • Clean up all stale eslint-disable comments from source files
  • EventEmitter: add once() method for one-time event subscriptions
  • Memory leak fix: move module-level checkedLoadedFor cache to Translator instance, preventing cross-instance state leakage
  • TypeScript: fix BackendModule generic parameter naming inconsistency between CJS and ESM type definitions
  • TypeScript: add once() method to i18n and ResourceStore type 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.projects config

Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Mend Renovate.

This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [i18next](https://www.i18next.com) ([source](https://github.com/i18next/i18next)) | dependencies | major | [`^25.3.2` → `^26.0.0`](https://renovatebot.com/diffs/npm/i18next/25.10.10/26.3.1) | --- ### Release Notes <details> <summary>i18next/i18next (i18next)</summary> ### [`v26.3.1`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2631) [Compare Source](https://github.com/i18next/i18next/compare/v26.3.0...v26.3.1) - fix(types): `t()` with a `keyPrefix` no longer pollutes its return type with sibling keys' values. A regression in 26.3.0 — the `[Res] extends [never]` guards added to `KeysBuilderWithReturnObjects` / `KeysBuilderWithoutReturnObjects` turned the builders into deferred conditional types, so `KeyPrefix<Ns>` stopped resolving to a literal union and `keyPrefix` inference widened to the whole namespace. Symptom: `useTranslation(ns, { keyPrefix: 'a.b' })` then `t('title')` would resolve to `'<a.b>.title' | '<other.path>.title' | ...` instead of just the scoped value. Affected every `react-i18next` user using `keyPrefix`. Restored to the eager 26.2.0 form. The same-namespace conflict handling from [#&#8203;2434](https://github.com/i18next/i18next/issues/2434) still works via `_DropConflictKeys` at the merge layer (in `options.d.ts`). Thanks [@&#8203;aaronrosenthal](https://github.com/aaronrosenthal) ([#&#8203;2436](https://github.com/i18next/i18next/pull/2436)). ### [`v26.3.0`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2630) [Compare Source](https://github.com/i18next/i18next/compare/v26.2.0...v26.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 single `CustomTypeOptions.resources` declaration (or fall back to typing dependency namespaces as `any`) because `resources` is a single property of an interface and TypeScript reports TS2717 when two declarations of the same property disagree. The new interface merges naturally across `declare module 'i18next'` blocks, so each package can ship its own `i18next.d.ts` independently. Per-property merge handles same-namespace contributions from multiple packages, and same-key/different-literal conflicts are silently dropped to avoid poisoning `t()` overload resolution. Fully backwards-compatible — existing `CustomTypeOptions.resources` augmentations continue to work, and both surfaces can coexist. Scalar options (`defaultNS`, `returnNull`, `enableSelector`, etc.) still belong on `CustomTypeOptions`. Thanks [@&#8203;sh3xu](https://github.com/sh3xu) ([#&#8203;2434](https://github.com/i18next/i18next/pull/2434)). Fixes [#&#8203;2409](https://github.com/i18next/i18next/issues/2409). ### [`v26.2.0`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2620) [Compare Source](https://github.com/i18next/i18next/compare/v26.1.0...v26.2.0) - feat(types): new `parseInterpolation` TypeOption (default `true`). When set to `false` in `CustomTypeOptions`, the type-level extractor stops parsing translation strings for `{{variable}}` patterns. Required by `i18next-icu` users — 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 by `InterpolationOptions` and is unaffected. Fixes [i18next-icu#85](https://github.com/i18next/i18next-icu/issues/85). - fix(types): expose `enableSelector` on `InitOptions` so `i18next.init({ enableSelector: 'strict' })` typechecks without a module augmentation. The runtime already reads `opts?.enableSelector` from init options; this lands the matching type declaration next to the other selector-resolution knobs. Accepts `false | true | 'optimize' | 'strict'`. Thanks [@&#8203;Faithfinder](https://github.com/Faithfinder) ([#&#8203;2431](https://github.com/i18next/i18next/pull/2431)) ### [`v26.1.0`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2610) [Compare Source](https://github.com/i18next/i18next/compare/v26.0.10...v26.1.0) - feat: `enableSelector: 'strict'` (TypeOptions + runtime option). Opt-in mode that drops the flattened-primary form from `NsResource` at 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 where `t($ => $.primary.foo)` typechecks but doesn't resolve under the default mode (see [#&#8203;2429](https://github.com/i18next/i18next/issues/2429)). Backward-compatible: default `enableSelector: false | true | 'optimize'` behavior is unchanged. Note: strict mode is incompatible with the [#&#8203;2405](https://github.com/i18next/i18next/issues/2405) pattern (keys whose names match sibling namespaces) — those users should stay on default mode. ### [`v26.0.10`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#26010) [Compare Source](https://github.com/i18next/i18next/compare/v26.0.9...v26.0.10) - feat: `getFixedT` accepts a fourth optional `fixedOpts` argument carrying `scopeNs` — the full namespace list the bound `t` was created for. The selector API uses `scopeNs` to detect when a path's first segment is a namespace prefix, **without** changing resolution scope. Resolution still uses the bound `ns` (a single primary string in the typical react-i18next setup), so plain `t('key')` lookups stay isolated to the primary namespace exactly as before — only `t($ => $.secondaryNs.foo)` selectors now route correctly under `useTranslation([nsA, nsB])`. Fixes the runtime side of [#&#8203;2429](https://github.com/i18next/i18next/issues/2429) for the `react-i18next` default-`nsMode` case. The 4th argument is opt-in: existing 3-arg `getFixedT(lng, ns, keyPrefix)` callers see no behavior change. ### [`v26.0.9`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2609) [Compare Source](https://github.com/i18next/i18next/compare/v26.0.8...v26.0.9) - fix(types): unformatted interpolation values are now typed as `string | number` (was `string`). i18next stringifies values at runtime, so requiring callers to wrap numbers in `String(...)` for plain `{{var}}` placeholders was unnecessary friction — and could mask the real problem when a non-string value was passed alongside multiple interpolation slots (the `t()` 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. The `count` variable remains `number`-only ### [`v26.0.8`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2608) [Compare Source](https://github.com/i18next/i18next/compare/v26.0.7...v26.0.8) - fix(types): restore the pre-v25.10.4 `ExistsFunction` shape so plain arrow functions can again be assigned to `ExistsFunction`-typed variables (TypeScript cannot infer type predicates through multi-overload assignment). Direct `i18next.exists(key)` calls still narrow `key` to `SelectorKey` — the predicate is now declared inline on `i18n.exists`. Custom wrappers that want the narrowing can type themselves as `typeof i18next.exists` [2425](https://github.com/i18next/i18next/issues/2425) ### [`v26.0.7`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2607) [Compare Source](https://github.com/i18next/i18next/compare/v26.0.6...v26.0.7) - fix: when a plural lookup misses, the `missingKey` debug log now shows the actual plural-resolved key (e.g. `foo.bar_many` for Polish `count: 14`) instead of the base key — making it obvious which plural category was expected and missing [2423](https://github.com/i18next/i18next/issues/2423) - chore: drop `@babel/runtime` runtime dependency. The build no longer generates any `@babel/runtime` imports, so the package is unused by consumers. Rollup now uses `babelHelpers: 'bundled'` so any helpers that are ever needed in the future will be inlined rather than imported externally [2424](https://github.com/i18next/i18next/issues/2424) - chore: stop emitting `dist/esm/i18next.bundled.js`. It was byte-identical to `dist/esm/i18next.js` because no helpers were being imported [2424](https://github.com/i18next/i18next/issues/2424) ### [`v26.0.6`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2606) [Compare Source](https://github.com/i18next/i18next/compare/v26.0.5...v26.0.6) Security release — all issues found via an internal audit. - security: warn when a translation string combines `escapeValue: false` with 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. redirect `lng`/`ns`). The default `escapeValue: true` configuration is unaffected because HTML-escaping neutralises the quote before `JSON.parse`. See the [security note in the Nesting docs](https://www.i18next.com/translation-function/nesting#security-note-interpolated-values-inside-a-nesting-options-block) for the full pattern and mitigations - security: apply `regexEscape` to `unescapePrefix` / `unescapeSuffix` on 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`/`*.key` files in `.gitignore` ### [`v26.0.5`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2605) [Compare Source](https://github.com/i18next/i18next/compare/v26.0.4...v26.0.5) - fix: `cloneInstance().changeLanguage()` no longer fails to update language state when the target language is not yet loaded — a race between `init()`'s deferred `load()` and the user's `changeLanguage()` could overwrite `isLanguageChangingTo`, causing `setLngProps` to be skipped [2422](https://github.com/i18next/i18next/issues/2422) ### [`v26.0.4`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2604) [Compare Source](https://github.com/i18next/i18next/compare/v26.0.3...v26.0.4) - fix(types): inline formatting options like `{{price, currency(EUR)}}` are now correctly resolved to their base format type (e.g. `number` for `currency`) instead of falling back to `string` [2378](https://github.com/i18next/i18next/issues/2378) ### [`v26.0.3`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2603) [Compare Source](https://github.com/i18next/i18next/compare/v26.0.2...v26.0.3) - fix(types): `addResourceBundle` now accepts an optional 6th `options` parameter (`{ silent?: boolean; skipCopy?: boolean }`) matching the runtime API [2419](https://github.com/i18next/i18next/issues/2419) ### [`v26.0.2`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2602) [Compare Source](https://github.com/i18next/i18next/compare/v26.0.1...v26.0.2) - fix(types): `t("key", {} as TOptions)` no longer produces a type error — the context constraint now bypasses strict checking when `context` is `unknown` (e.g. from `TOptions`) [2418](https://github.com/i18next/i18next/issues/2418) ### [`v26.0.1`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#26010) [Compare Source](https://github.com/i18next/i18next/compare/v26.0.0...v26.0.1) - feat: `getFixedT` accepts a fourth optional `fixedOpts` argument carrying `scopeNs` — the full namespace list the bound `t` was created for. The selector API uses `scopeNs` to detect when a path's first segment is a namespace prefix, **without** changing resolution scope. Resolution still uses the bound `ns` (a single primary string in the typical react-i18next setup), so plain `t('key')` lookups stay isolated to the primary namespace exactly as before — only `t($ => $.secondaryNs.foo)` selectors now route correctly under `useTranslation([nsA, nsB])`. Fixes the runtime side of [#&#8203;2429](https://github.com/i18next/i18next/issues/2429) for the `react-i18next` default-`nsMode` case. The 4th argument is opt-in: existing 3-arg `getFixedT(lng, ns, keyPrefix)` callers see no behavior change. ### [`v26.0.0`](https://github.com/i18next/i18next/blob/HEAD/CHANGELOG.md#2600) [Compare Source](https://github.com/i18next/i18next/compare/v25.10.10...v26.0.0) **This is a major breaking release:** ##### Breaking Changes - **Remove deprecated `initImmediate` option** — the backward-compatibility mapping from `initImmediate` to `initAsync` (introduced in v24) has been removed. Use `initAsync` instead. - **Remove legacy `interpolation.format` function** — 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](https://www.i18next.com/translation-function/formatting) using `i18next.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 `showSupportNotice` option and all related internal suppression logic (`globalThis.__i18next_supportNoticeShown`, `I18NEXT_NO_SUPPORT_NOTICE` env var). See our blog post for the [full story](https://www.locize.com/blog/i18next-support-notice). - **Remove `simplifyPluralSuffix` option** — this option was unused by the core PluralResolver (which relies entirely on `Intl.PluralRules`). It only had an effect in the old v1/v2/v3 compatibility layer. The v4 test compatibility layer now defaults to `true` internally. - **Remove deprecated `@babel/polyfill`** from devDependencies. ##### Improvements - **Code modernization** across all source files: - Replace `indexOf() > -1` / `indexOf() < 0` with `.includes()` (\~40+ occurrences) - Replace `indexOf() === 0` with `.startsWith()` where appropriate - Replace `var` with `const`, `'' + object` with `String(object)`, `.substring()` with `.slice()` - Replace `.apply(observer, [event, ...args])` with direct call `observer(event, ...args)` - Remove unnecessary `.call(this, ...)` in BackendConnector retry logic - Fix `array-callback-return` in LanguageUtils `getBestMatchFromCodes` - Clean up all stale `eslint-disable` comments from source files - **EventEmitter**: add `once()` method for one-time event subscriptions - **Memory leak fix**: move module-level `checkedLoadedFor` cache to Translator instance, preventing cross-instance state leakage - **TypeScript**: fix `BackendModule` generic parameter naming inconsistency between CJS and ESM type definitions - **TypeScript**: add `once()` method to `i18n` and `ResourceStore` type interfaces - **ESLint 9**: migrate from ESLint 8 (airbnb-base) to ESLint 9 flat config with [neostandard](https://github.com/neostandard/neostandard) - **Vitest 4**: upgrade from vitest 3 to vitest 4, migrate workspace files to `test.projects` config </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My45Ni4wIiwidXBkYXRlZEluVmVyIjoiNDMuMjEzLjMiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbXX0=-->
Update dependency i18next to v26
All checks were successful
ci/woodpecker/pr/testbuild Pipeline was successful
33012ba899
All checks were successful
ci/woodpecker/pr/testbuild Pipeline was successful
This pull request can be merged automatically.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin renovate/i18next-26.x:renovate/i18next-26.x
git switch renovate/i18next-26.x

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff renovate/i18next-26.x
git switch renovate/i18next-26.x
git rebase main
git switch main
git merge --ff-only renovate/i18next-26.x
git switch renovate/i18next-26.x
git rebase main
git switch main
git merge --no-ff renovate/i18next-26.x
git switch main
git merge --squash renovate/i18next-26.x
git switch main
git merge --ff-only renovate/i18next-26.x
git switch main
git merge renovate/i18next-26.x
git push origin main
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Bluemedia/LibreCharge!554
No description provided.