Skip to content

Bump the identifier group across 1 directory with 9 updates - #291

Closed
dependabot[bot] wants to merge 1 commit into
masterfrom
dependabot/bun/identifier/identifier-61803249f8
Closed

dependabot[bot] wants to merge 1 commit into
masterfrom
dependabot/bun/identifier/identifier-61803249f8

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Bumps the identifier group with 9 updates in the /identifier directory:

Package From To
i18next 26.4.3 26.5.6
react 19.3.0 19.3.1
react-dom 19.3.0 19.3.1
react-i18next 17.0.16 17.1.3
react-router 8.4.0 8.5.0
@biomejs/biome 2.5.15 2.6.2
@testing-library/user-event 14.6.7 14.6.8
jsdom 30.0.1 30.1.3
vite 8.3.4 8.3.5

Updates i18next from 26.4.3 to 26.5.6

Release notes

Sourced from i18next's releases.

v26.5.6

  • fix: cloneInstance({ forkResourceStore: true }) now copies the resources at every level. It copied them only down to the namespace objects, so nested keys and arrays stayed shared with the original instance: addResource() with a nested key (fork.addResource('en', 'translation', 'greeting.hello', 'Hi')) or a deep addResourceBundle() on the fork also changed the original instance and every other fork. Flat keys were already isolated. Forking a large store takes a bit longer: with 300k keys in nested groups, about 11 ms instead of 3 ms per fork. Clones without forkResourceStore still share the store as before. Thanks @​nk-batman21 (#2456, follow-up to #2270).

v26.5.5

  • fix: with the default skipOnVariables: true, a {{placeholder}} inside a value inserted with an unescaped {{- var}} now stays literal, as it already did for {{var}}. The escape pass ran after the unescaped values were written and scanned them again, so t('{{- a}}', { a: '{{b}}', b: 'c' }) returned 'c' instead of '{{b}}'. With pre-built HTML that carries user text, like t('You may contact {{name}} at {{- emailHTML}}.', { name, emailHTML }), that text could pull another variable of the same t() call into the output. Results with skipOnVariables: false, and values without placeholders, are unchanged. Compatibility note: a {{- var}} value whose placeholders were meant to be filled from the same t() call now keeps them literally; skipOnVariables: false restores the old behavior. Thanks @​nk-batman21 (#2455, reported in #1595).

v26.5.4

  • fix: with the default skipOnVariables: true, a {{placeholder}} inside an interpolated value now stays literal also when the same placeholder appears later in the translation. Each value was written with String.replace, which replaces the first copy of the placeholder text, and that could be the copy inside an earlier value: t('{{name}} has {{count}} items', { name: '{{count}}', count: 5 }) returned '5 has {{count}} items' instead of '{{count}} has 5 items'. The value is now written at the position of the matched placeholder. Results with skipOnVariables: false are unchanged. Thanks @​nk-batman21 (#2454, reported in #1595).
  • fix: with useRawValueToEscape: true, a non-string value in an unescaped {{- var}} placeholder or with escapeValue: false no longer throws val.replace is not a function; it is converted to a string like any other value.

v26.5.3

  • fix(types): with the selector API, a plural key now requires count also when the call passes an explicit ns. t(($) => $.item) already failed without count, but t(($) => $.item, { ns: 'items' }) compiled, although at runtime it looks up item instead of item_one / item_other and returns the key. It now fails the same way, also with ordinal: true, defaultValue, an ns array, a key prefix and i18n.t. Calls with count, context, returnObjects: true and arrays of selectors, as well as return types, are unchanged. Thanks @​nyarthan (#2452).

v26.5.2

  • fix(types): on TypeScript 7, a t() call with a missing, misspelled or wrongly typed option now reports that option again (Property 'album' is missing, Type 'string' is not assignable to type 'number'), as TypeScript 5 and 6 do. TypeScript 7 elaborated the error against the default-value signature instead and ended in '{ count: 3; albm: "Summer"; }' is not assignable to type 'string': on a failed call TypeScript explains the last of the equally matching signatures, and TypeScript 7 sorts the 3-element [key, defaultValue, options?] last. It is now written as two signatures, [key, defaultValue] and [key, defaultValue, options]. This affects the default key checks with i18next {{name}} messages as well as parseInterpolation: 'icu' and 'mf2'. Which calls compile, their return types and the error positions are unchanged on TypeScript 5.9, 6 and 7.

v26.5.1

  • perf(types): type-checking t() calls against a large namespace is no longer quadratic in the number of keys. TypeScript does not cache keyof of an object type, and the types rebuilt the union of all keys of a namespace once per key while building the key union, and again in every t() call to look up the return type. Both now use a cached key union, and a literal key is looked up directly instead of being intersected with every key. With 5,000 keys in one namespace and one call per key, the check time went from 14.8s to 1.1s (TypeScript 6); with 1,000 keys from 0.75s to 0.27s. Keys, return types and errors are unchanged.
  • perf(types): the selector API (enableSelector: true / 'strict') with context is no longer quadratic in the size of an object. To decide which keys a context keeps, the types scanned all keys of the object once for every key, also when TypeScript checks the selector with context widened to string. With 1,000 keys plus one context variant each, a namespace took 18.7s and failed with "Type instantiation is excessively deep and possibly infinite" (TS2589); 2,500 and more ran out of memory. The context variants of an object are now collected once, in one pass over its keys: 1,000 keys check in 0.69s, 5,000 in 3.1s. Long keys (whole sentences with keySeparator: false) work as before. Selected values and errors are unchanged.

v26.5.0

  • feat(types): parseInterpolation: 'icu' and parseInterpolation: 'mf2' type t() options from the message's ICU MessageFormat arguments (i18next-icu) or MessageFormat 2 variables (i18next-mf2), so ICU and MF2 users no longer need parseInterpolation: false and lose argument checking. Missing, misspelled and wrongly typed arguments fail, and so does leaving out the options for a message with arguments (t('greeting')); that error names the missing arguments. Opt-in, default true is unchanged.
    • ICU: {name} takes string | number, {n, number}, plural and selectordinal take number, {d, date} and {t, time} take Date, select takes its case keys or any string (for other), and arguments nested in cases are required too. # and tags are not arguments, apostrophe quoting is read like intl-messageformat does.
    • MF2: {$name} takes string | number, a variable annotated with :number, :integer, :currency, :percent or :unit (inline or through .input / .local) takes number, :datetime, :date and :time take Date, :string takes string, option and markup variables (minimumFractionDigits=$digits, {#link href=$url}) are required too, .local variables are not arguments, and |quoted literals| and \{ escapes are skipped.
    • interpolationFormatTypeMap overrides a type by ICU format or MF2 function name, e.g. date: Date | number or a custom uppercase: string.
    • Applies to t(), getFixedT(), i18n.t, key prefixes, namespaces, the selector API and react-i18next's Trans values. Messages need literal types, as the resources file from i18next-cli's types command has them.
    • Type-check cost with 1,000 messages and one call each: 1.35s instead of 0.86s with false (TypeScript 6), 0.5s instead of 0.26s with TypeScript 7. Messages that no call uses cost nothing.
  • fix(types): with the default (non-strict) key checks, an options object with a missing or misspelled interpolation variable now reports the missing variable (Property 'name' is missing) instead of '{ nmae: string }' is not assignable to type 'string' from the default-value overload.

v26.4.7

  • perf: cloneInstance() no longer inherits preload. loadResources() adds every preload language to each load, and clones copied preload from the parent, so a clone's init() and every changeLanguage() walked all preloaded languages × all namespaces through queueLoad() / hasResourceBundle(), although the parent had already loaded them into the shared store. With i18next-http-middleware (one clone + changeLanguage() per request), 25 preloaded languages and 20 namespaces, that was most of the per-request CPU: the reproduction from the issue went from ~90 µs to ~10 µs per request, the same as with a single language. A clone now only loads what it uses itself: its changeLanguage() no longer waits for parent preload languages that are still loading (the parent's own init() still does), and clone.loadNamespaces() loads the new namespace for the clone's language and fallbacks instead of every preloaded language. clone.loadLanguages() works as before, the parent instance is unchanged, and passing preload to cloneInstance() keeps the old behavior. Thanks @​theMostCuriousHomunculus for the detailed report (#2451).

v26.4.6

  • fix: a fallback language whose formatted code is already in the hierarchy is no longer added a second time. toResolveHierarchy() checked the raw fallbackLng value against the list, but the list holds formatted codes, so any fallback written differently from its formatted form slipped through: lng: 'de-CH' with fallbackLng: 'de-ch' gave languages ['de-CH', 'de', 'de-CH'], and the same happened with fallbackLng: 'EN' + cleanCode, lowerCaseLng, and Intl aliases (iw-IL → he-IL). Missing keys were looked up in the same language twice. Only exact duplicates are removed; the order is unchanged. Thanks @​lprnmns (#2450).

v26.4.5

  • fix: hasLoadedNamespace(ns, { lng }) no longer stays false forever when the passed in lng is loaded under another code, or not at all. It checked the load state of the raw lng, but loadLanguages() stores a language under its resolved code (de-ch → de-CH, de-CH → de with load: 'languageOnly') and skips a lng outside supportedLngs entirely (only the fallback gets loaded), so that state never got set. react-i18next's useTranslation(ns, { lng }) then never became ready: with useSuspense it kept throwing an already resolved promise and React retried forever (100% CPU, SSR never finished), without it the load effect re-rendered in a loop. It now checks the code the language is actually loaded under, and for a lng outside supportedLngs only waits for the fallback, which is also what t() resolves to. Calls without lng and the precheck (react-i18next's bindI18n: 'languageChanging') are unchanged (react-i18next#1934).

v26.4.4

  • fix(security): the nesting regexp no longer backtracks exponentially (ReDoS) on an unclosed $t(. Its repeated group had overlapping alternatives ([^()"']+ inside (?:...)*?, and inside parentheses [^()] also matched quotes), so a string containing $t( without a closing ) made the engine try every way to split the text: about 2x the runtime per extra character, and a ~25 character value hung t() for minutes. With the default config this was reachable through any interpolated value (t('greet', { name: '$t(aaaaaaaaaaaaaaaaaaaaaaaa' })): escaping does not touch $, t or (, and the skipOnVariables check runs the regexp on the interpolated result, so nest: false did not help either. Every alternative now starts with a different character (plain char, ", ' or (), so there is only one way to match and the cost is linear. Quoted strings and one level of parentheses in nesting options keep working (#2336). The only difference: a lone " or ' inside unquoted parentheses within $t(...) is no longer matched. Affects 25.3.3 to 26.4.3. Thanks to Anisetti Chaitanya Eshwar Prasad for the responsible disclosure.
  • fix(security): nest() now resolves $t(...) in a single pass and no longer nests text that came out of a resolved value. Every nested lookup reset the shared nesting regexp, so the loop started over from the beginning of the string after each match. That had two effects. First, a $t(...) inside a variable that the nested lookup deliberately kept literal (default skipOnVariables: true) was resolved anyway by the outer loop: with outer: 'A $t(inner) B' and inner: 'Hi {{name}}', t('outer', { name: '$t(secret)' }) rendered the secret translation. It now stays A Hi $t(secret) B, the same as without the outer nesting; with skipOnVariables: false it is still resolved. Second, the cost was quadratic when an unclosed $t( preceded many nestings, which matters when an app passes untrusted input as the key itself (t(userInput)): 20,000 nestings took ~1.4 s, now ~25 ms. The resolved value is now sliced into the result instead of going through String.replace, so $&, $`, $' and $$ stay literal as before (26.4.2).
Changelog

Sourced from i18next's changelog.

26.5.6

  • fix: cloneInstance({ forkResourceStore: true }) now copies the resources at every level. It copied them only down to the namespace objects, so nested keys and arrays stayed shared with the original instance: addResource() with a nested key (fork.addResource('en', 'translation', 'greeting.hello', 'Hi')) or a deep addResourceBundle() on the fork also changed the original instance and every other fork. Flat keys were already isolated. Forking a large store takes a bit longer: with 300k keys in nested groups, about 11 ms instead of 3 ms per fork. Clones without forkResourceStore still share the store as before. Thanks @​nk-batman21 (#2456, follow-up to #2270).

26.5.5

  • fix: with the default skipOnVariables: true, a {{placeholder}} inside a value inserted with an unescaped {{- var}} now stays literal, as it already did for {{var}}. The escape pass ran after the unescaped values were written and scanned them again, so t('{{- a}}', { a: '{{b}}', b: 'c' }) returned 'c' instead of '{{b}}'. With pre-built HTML that carries user text, like t('You may contact {{name}} at {{- emailHTML}}.', { name, emailHTML }), that text could pull another variable of the same t() call into the output. Results with skipOnVariables: false, and values without placeholders, are unchanged. Compatibility note: a {{- var}} value whose placeholders were meant to be filled from the same t() call now keeps them literally; skipOnVariables: false restores the old behavior. Thanks @​nk-batman21 (#2455, reported in #1595).

26.5.4

  • fix: with the default skipOnVariables: true, a {{placeholder}} inside an interpolated value now stays literal also when the same placeholder appears later in the translation. Each value was written with String.replace, which replaces the first copy of the placeholder text, and that could be the copy inside an earlier value: t('{{name}} has {{count}} items', { name: '{{count}}', count: 5 }) returned '5 has {{count}} items' instead of '{{count}} has 5 items'. The value is now written at the position of the matched placeholder. Results with skipOnVariables: false are unchanged. Thanks @​nk-batman21 (#2454, reported in #1595).
  • fix: with useRawValueToEscape: true, a non-string value in an unescaped {{- var}} placeholder or with escapeValue: false no longer throws val.replace is not a function; it is converted to a string like any other value.

26.5.3

  • fix(types): with the selector API, a plural key now requires count also when the call passes an explicit ns. t(($) => $.item) already failed without count, but t(($) => $.item, { ns: 'items' }) compiled, although at runtime it looks up item instead of item_one / item_other and returns the key. It now fails the same way, also with ordinal: true, defaultValue, an ns array, a key prefix and i18n.t. Calls with count, context, returnObjects: true and arrays of selectors, as well as return types, are unchanged. Thanks @​nyarthan (#2452).

26.5.2

  • fix(types): on TypeScript 7, a t() call with a missing, misspelled or wrongly typed option now reports that option again (Property 'album' is missing, Type 'string' is not assignable to type 'number'), as TypeScript 5 and 6 do. TypeScript 7 elaborated the error against the default-value signature instead and ended in '{ count: 3; albm: "Summer"; }' is not assignable to type 'string': on a failed call TypeScript explains the last of the equally matching signatures, and TypeScript 7 sorts the 3-element [key, defaultValue, options?] last. It is now written as two signatures, [key, defaultValue] and [key, defaultValue, options]. This affects the default key checks with i18next {{name}} messages as well as parseInterpolation: 'icu' and 'mf2'. Which calls compile, their return types and the error positions are unchanged on TypeScript 5.9, 6 and 7.

26.5.1

  • perf(types): type-checking t() calls against a large namespace is no longer quadratic in the number of keys. TypeScript does not cache keyof of an object type, and the types rebuilt the union of all keys of a namespace once per key while building the key union, and again in every t() call to look up the return type. Both now use a cached key union, and a literal key is looked up directly instead of being intersected with every key. With 5,000 keys in one namespace and one call per key, the check time went from 14.8s to 1.1s (TypeScript 6); with 1,000 keys from 0.75s to 0.27s. Keys, return types and errors are unchanged.
  • perf(types): the selector API (enableSelector: true / 'strict') with context is no longer quadratic in the size of an object. To decide which keys a context keeps, the types scanned all keys of the object once for every key, also when TypeScript checks the selector with context widened to string. With 1,000 keys plus one context variant each, a namespace took 18.7s and failed with "Type instantiation is excessively deep and possibly infinite" (TS2589); 2,500 and more ran out of memory. The context variants of an object are now collected once, in one pass over its keys: 1,000 keys check in 0.69s, 5,000 in 3.1s. Long keys (whole sentences with keySeparator: false) work as before. Selected values and errors are unchanged.

26.5.0

  • feat(types): parseInterpolation: 'icu' and parseInterpolation: 'mf2' type t() options from the message's ICU MessageFormat arguments (i18next-icu) or MessageFormat 2 variables (i18next-mf2), so ICU and MF2 users no longer need parseInterpolation: false and lose argument checking. Missing, misspelled and wrongly typed arguments fail, and so does leaving out the options for a message with arguments (t('greeting')); that error names the missing arguments. Opt-in, default true is unchanged.
    • ICU: {name} takes string | number, {n, number}, plural and selectordinal take number, {d, date} and {t, time} take Date, select takes its case keys or any string (for other), and arguments nested in cases are required too. # and tags are not arguments, apostrophe quoting is read like intl-messageformat does.
    • MF2: {$name} takes string | number, a variable annotated with :number, :integer, :currency, :percent or :unit (inline or through .input / .local) takes number, :datetime, :date and :time take Date, :string takes string, option and markup variables (minimumFractionDigits=$digits, {#link href=$url}) are required too, .local variables are not arguments, and |quoted literals| and \{ escapes are skipped.
    • interpolationFormatTypeMap overrides a type by ICU format or MF2 function name, e.g. date: Date | number or a custom uppercase: string.
    • Applies to t(), getFixedT(), i18n.t, key prefixes, namespaces, the selector API and react-i18next's Trans values. Messages need literal types, as the resources file from i18next-cli's types command has them.
    • Type-check cost with 1,000 messages and one call each: 1.35s instead of 0.86s with false (TypeScript 6), 0.5s instead of 0.26s with TypeScript 7. Messages that no call uses cost nothing.
  • fix(types): with the default (non-strict) key checks, an options object with a missing or misspelled interpolation variable now reports the missing variable (Property 'name' is missing) instead of '{ nmae: string }' is not assignable to type 'string' from the default-value overload.

26.4.7

  • perf: cloneInstance() no longer inherits preload. loadResources() adds every preload language to each load, and clones copied preload from the parent, so a clone's init() and every changeLanguage() walked all preloaded languages × all namespaces through queueLoad() / hasResourceBundle(), although the parent had already loaded them into the shared store. With i18next-http-middleware (one clone + changeLanguage() per request), 25 preloaded languages and 20 namespaces, that was most of the per-request CPU: the reproduction from the issue went from ~90 µs to ~10 µs per request, the same as with a single language. A clone now only loads what it uses itself: its changeLanguage() no longer waits for parent preload languages that are still loading (the parent's own init() still does), and clone.loadNamespaces() loads the new namespace for the clone's language and fallbacks instead of every preloaded language. clone.loadLanguages() works as before, the parent instance is unchanged, and passing preload to cloneInstance() keeps the old behavior. Thanks @​theMostCuriousHomunculus for the detailed report (#2451).

26.4.6

  • fix: a fallback language whose formatted code is already in the hierarchy is no longer added a second time. toResolveHierarchy() checked the raw fallbackLng value against the list, but the list holds formatted codes, so any fallback written differently from its formatted form slipped through: lng: 'de-CH' with fallbackLng: 'de-ch' gave languages ['de-CH', 'de', 'de-CH'], and the same happened with fallbackLng: 'EN' + cleanCode, lowerCaseLng, and Intl aliases (iw-IL → he-IL). Missing keys were looked up in the same language twice. Only exact duplicates are removed; the order is unchanged. Thanks @​lprnmns (#2450).

26.4.5

  • fix: hasLoadedNamespace(ns, { lng }) no longer stays false forever when the passed in lng is loaded under another code, or not at all. It checked the load state of the raw lng, but loadLanguages() stores a language under its resolved code (de-ch → de-CH, de-CH → de with load: 'languageOnly') and skips a lng outside supportedLngs entirely (only the fallback gets loaded), so that state never got set. react-i18next's useTranslation(ns, { lng }) then never became ready: with useSuspense it kept throwing an already resolved promise and React retried forever (100% CPU, SSR never finished), without it the load effect re-rendered in a loop. It now checks the code the language is actually loaded under, and for a lng outside supportedLngs only waits for the fallback, which is also what t() resolves to. Calls without lng and the precheck (react-i18next's bindI18n: 'languageChanging') are unchanged (react-i18next#1934).

26.4.4

... (truncated)

Commits

Updates react from 19.3.0 to 19.3.1

Release notes

Sourced from react's releases.

19.3.1 (October 14th, 2026)

React Server Components

Commits

Updates react-dom from 19.3.0 to 19.3.1

Release notes

Sourced from react-dom's releases.

19.3.1 (October 14th, 2026)

React Server Components

Commits

Updates react-i18next from 17.0.16 to 17.1.3

Changelog

Sourced from react-i18next's changelog.

17.1.3

  • fix(IcuTrans): numeric HTML entities above U+FFFF, like emoji, now decode to the right character. "Hello &#x1F44B; <0>friend</0> &[#127881](https://github.com/i18next/react-i18next/issues/127881);" rendered U+F44B and U+F389, private-use glyphs that usually show as a box, instead of 👋 and 🎉: the decoder used String.fromCharCode, which keeps only the low 16 bits of the code point. This shows up with translations that a TMS or CMS exports HTML-encoded. Entities above U+10FFFF, which are no valid code points, now stay as written instead of becoming U+0000. Entities below U+10000, including surrogate pairs written as two entities, decode as before. Thanks @​nk-batman21 (#1940).

17.1.2

  • fix(Trans): when the only child is a string, a tag whose index the children don't have now renders its own text. <Trans i18nKey="welcome">Welcome</Trans> with "Welcome <1>friend</1>" rendered Welcome e, and defaults="Hi <1>there</1>" with the child Hi rendered Hi i. The fallback for a single object of components ({{ 1: <strong /> }}) looked the tag up on the string and rendered one of its characters. It now applies only when that child is an object, so {{ 1: <strong /> }} renders as before, and the tag falls back to its inner text, as it already did with several children or with a number or an element as the only child. This also stops a single-entry array child holding null ({[null]}, e.g. from a .map that returned null) from throwing Cannot read properties of null. Thanks @​Cayan (#1939).

17.1.1

  • fix(Trans): with components as an object with index keys, the component for key 0 is now rendered. components={{ 0: <a href={path} /> }} with "You're eligible. <0>Get started here.</0>" rendered the text without the link, a self-closing <0/> rendered nothing, and in <0>a <1>b</1></0> both elements were lost, while keys 1 and up and the array form worked. The object was passed on as the indexed children, so <0> resolved to the object itself. It is now looked up by key, like a named components map. This also fixes an array components next to react.transDefaultProps.components, which the merge turns into such an object ({ Bold, 0, 1 }) and so lost its first entry, and a self-closing named tag in a mixed object ({ 0: <a />, Bold: <b /> } with <Bold/>), which rendered as the text <Bold />. Arrays, named maps and index objects starting at 1 render as before. Thanks @​nk-batman21 (#1938).

17.1.0

  • feat(types): with i18next's new parseInterpolation: 'icu' (or 'mf2') type option (i18next v26.5.0), the values of IcuTrans and IcuTransWithoutContext are typed from the message of i18nKey, like the options of t(): a misspelled argument, a value of the wrong type or a value meant for another key is a type error. values was Record<string, any> before, and still is with any other parseInterpolation setting. values stays optional, as on Trans. useTranslation's t and Trans values get the checks from i18next's types without changes here.
  • fix(types): IcuTrans and IcuTransWithoutContext now infer the literal i18nKey (const type parameter, as Trans does), so props that depend on the key are checked against that key instead of all keys of the namespace.

17.0.21

  • fix(IcuTrans): explicit values now win over interpolation.defaultVariables, as they do in t(). IcuTrans merged them the other way round, so <IcuTrans values={{ user: 'John Doe' }} /> rendered the configured default variable user instead of John Doe. Trans had the same inverted merge and is fixed too. Compatibility note: only names that are set both in values and in defaultVariables render differently.
  • feat: new entry point react-i18next/IcuTransWithoutContext (with types) for React Server Components. Importing IcuTransWithoutContext from react-i18next in a Server Component could fail the build with createContext is not a function, because the main entry creates the React context when it is loaded. Like react-i18next/TransWithoutContext, the new entry point does not.
  • fix(build): the ESM build's dist/es/package.json now declares "sideEffects": false, like the root package.json already did. Bundlers use the nearest package.json, so the ESM build counted as having side effects and unused exports were kept: an app that only uses Trans still bundled IcuTrans with its HTML entity decoder, useTranslation and use-sync-external-store. With esbuild, a Trans-only bundle (React and i18next external) goes from 20.9 KB to 11.6 KB minified, 8.3 KB to 5.0 KB gzipped.
  • docs: the icu.macro Babel macro is now marked as deprecated in favour of using IcuTrans directly. It fails on Babel 8 (t.jSXIdentifier is not a function), <Plural count={count}> renders the raw ICU message, and a React key on <Plural>/<Select> becomes an ICU case. It keeps working on Babel 7 and is not removed. The IcuTrans docs page has a corrected example and props table and covers Server Components.

17.0.20

  • fix: useTranslation no longer suspends when a missing namespace is loaded by a synchronous backend. With useSuspense (the default), a namespace that wasn't in the store yet always made the component throw the loading promise, even when the backend had already delivered the resources while that promise was being created. React then showed the Suspense fallback and rendered again right away, which appears as a fallback flash (a white flash in React Native) and costs performance. The hook now starts the load first, checks the store again and only suspends if the namespace is still missing. This helps every backend that calls back synchronously, for example i18next-resources-to-backend with a static resources object or a loader that returns the data directly. Async backends, and an instance that isn't initialized yet, still suspend as before. Thanks @​oblador (#1937).

17.0.19

  • fix: useTranslation with an inline selector keyPrefix (useTranslation('ns', { keyPrefix: ($) => $.role })) returned a new t on every render, so every effect, useCallback and useMemo depending on t ran again each time. The cached t was compared against the keyPrefix function itself, and an inline arrow is a new function on every render. It is now compared against the key the selector resolves to (with the same options and namespace list getFixedT resolves it with), so t keeps its identity as long as the resolved prefix does, just like a string keyPrefix. A selector that resolves to a different key still gets a new t, and i18next still resolves the selector on each t call as before. Fixes #1936.
  • fix: useTranslation kept returning the previous t when only the namespace (useTranslation('a') → useTranslation('b')) or only the i18n instance (another instance with the same language, via props or I18nextProvider) changed on a mounted component. That t kept resolving against the old namespace or instance until something else (the language, the ready state, a bound i18n event) produced a new one. Both are now part of the check that decides whether the cached t can be reused.

17.0.18

  • fix(Trans): with shouldUnescape, the default unescape now turns &nbsp; and &[#160](https://github.com/i18next/react-i18next/issues/160); into a no-break space (U+00A0) instead of a regular space (U+0020). The regular space dropped what the entity is for: u&nbsp;nás or 10&nbsp;km could wrap across lines, and consecutive &nbsp;s collapsed into one space. This also matches IcuTrans, whose entity decoder already mapped &nbsp; to U+00A0. Compatibility note: only affects shouldUnescape; snapshots or exact textContent comparisons of such text now contain U+00A0 (Testing Library's default normalizer still matches it as a space). A custom react.unescape function can restore the old mapping for text nodes. Thanks @​lprnmns (#1935).

17.0.17

  • perf: useTranslation no longer unsubscribes and resubscribes its i18n listeners on every render. The subscribe callback handed to useSyncExternalStore depended on the merged options object, which is rebuilt whenever props is a new object: with no options (the {} default), with options passed inline (useTranslation('ns', { keyPrefix })), and through withTranslation and <Translation>. A new subscribe makes React resubscribe, so each render of each caller ran i18n.off and i18n.on in an extra effect. It now depends only on the instance and the bindI18n/bindI18nStore event names. No updates were ever missed, because React re-checks the snapshot after resubscribing; this only removes the churn, which adds up with many mounted components that re-render often. Reported via next-i18next#2349.
Commits

Updates react-router from 8.4.0 to 8.5.0

Release notes

Sourced from react-router's releases.

v8.5.0

See the changelog for release notes: https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v850

Changelog

Sourced from react-router's changelog.

v8.5.0

Minor Changes

  • Deprecate React Router's view transition APIs in favor of React's <ViewTransition> component, available in React 19.3 and later (#15493)
    • Deprecate the viewTransition props/options, useViewTransitionState, and NavLink's isTransitioning render prop and transitioning class
    • Preserve existing behavior, including support for older React versions
    • See the migration guide for a navigation example and compatibility considerations

Patch Changes

  • Fix <Await> failing to server render promises decoded from an RSC payload, which caused the Suspense boundary to switch to client rendering (#15597)
  • Declare @types/react and @types/react-dom as optional peer dependencies so the shipped type definitions resolve React types under strict (non-hoisted) node_modules layouts (#15528)
  • Fix the unstable_useRouterState documentation example to call the imported alias (#15535)
  • Render the HydrateFallback of a route discovered through patchRoutesOnNavigation during initial hydration (#15537)
    • Routes discovered during initial hydration are now exposed in state.matches while their loaders run, so <RouterProvider> renders down to the discovered route's HydrateFallback instead of rendering nothing
  • Fix router state recovery when updates occur before RouterProvider subscribes, including when other subscribers are already attached, and report current client errors once without replaying server errors during hydration (#15637)
  • Fix matchPath not treating a static segment as optional when it contains characters outside [\w-] (#15425)
  • Fix an RSC server crash when a client aborts a document request while the HTML stream waits for the RSC payload (#15612)
  • Stop revalidating a fetcher after fetcher.reset(), so its cleared data no longer comes back on the next revalidation (#15633)

Unstable Changes

⚠️ Unstable features are not recommended for production use

  • Add an unstable_fetch prop to <HydratedRouter> to customize JavaScript-issued manifest and server data requests in conventional Framework Mode (#15586)
    • The function receives the intended request as well as context identifying the type of request
    • Data request context includes navigationType ("PUSH", "REPLACE", or "POP" for navigation-initiated requests, including reloaded fetchers; null otherwise)
      • Data strategies receive equivalent metadata through unstable_initiator and unstable_navigationType
    • The custom fetch context is a discriminated union, so narrowing type to "navigation" guarantees a non-null navigationType, while other data requests have a null navigationType
      • Fetchers reloaded after an initialization redirect retain the "initialization" type and include their fetcher key
    • Like other router initialization options, the implementation is captured when the singleton router is created and thus subsequent prop changes are ignored
    • Browser-managed data prefetches from <Link prefetch> use native <link rel="prefetch"> elements and do not call the custom implementation
    • Use the callback for custom fetch options, custom headers, safe request retries, or response header inspection
    • Return response bodies unchanged so React Router can decode its manifest and Turbo Stream data protocols
  • Support API-only Framework Mode with runtime server data loading, actions, revalidation, and lazy route discovery (#15601)
    • Hydrate prerendered pages from build-time data and fetch server loader data when hydrating a SPA fallback
    • Preserve normal loader revalidation and server-action support for eagerly loaded and lazily discovered routes, and honor loader opt-outs when making server data requests
  • Add unstable_useRouteDiscovery for application-controlled route discovery in conventional Framework Mode (#15602)
    • Discover selected destinations or load the running client's full route manifest without loading route modules
    • Compose manifest-mismatch handlers, with shared recovery and cancellation that preserves application state
    • Keep full-manifest failures catchable without rendering error boundaries, whether mismatch handlers use the hook or event's loadAllRoutes()
    • Cancel pending revalidation alongside a canceled navigation, retaining existing data and settling interrupted fetchers before restoring Back/Forward history
    • Enable future.unstable_customRouteDiscovery to opt in
      • Apps without the flag retain existing discovery behavior
    • Call event.defaultBehavior() from a custom mismatch handler to explicitly run built-in recovery
  • Return middleware short-circuit responses as-is for document requests in RSC modes, including resource routes, instead of decoding non-RSC bodies as Flight (#15628)
    • Include server middleware in both eager and lazy RSC route configuration types
    • Preserve HTML rendering for cached Flight responses returned by middleware, and pass through raw responses that replace the result of next()
Commits
  • 4fe4525 Release v8.5.0 (#15515)
  • 358001c docs: prepare v8.5.0 release notes
  • 5ff8294 Fix RouterProvider initialization recovery with existing subscribers (#15637)
  • d86f6b4 Add opt-in application-controlled route discovery (#15602)
  • 19f75c0 Default single-fetch data strategy to native fetch (#15638)
  • 5e94053 Fix \<Await> server rendering for RSC promises (#15597)
  • 843230c fix(react-router): stop the RSC HTML stream when it is cancelled during flush...
  • 08ee782 fix(react-router): stop revalidating a fetcher after reset (#15633)
  • 6549ab0 fix(rsc): tag middleware short-circuit responses as React-Router-Resource (#1...
  • a1422f1 fix: render HydrateFallback of routes discovered during initial hydration (#1...
  • Additional commits viewable in compare view

Updates @biomejs/biome from 2.5.15 to 2.6.2

Release notes

Sourced from @​biomejs/biome's releases.

Biome CLI v2.6.2

2.6.2

Minor Changes

  • #11479 5c60ba8 Thanks @​nhedger! - Added a --git flag to biome init. The flag enables Git VCS integration and sets vcs.useIgnoreFile to true in the generated configuration, even when the command runs outside a Git repository.

  • #11742 3a1356d Thanks @​Netail! - Added the biome migrate stylelint command. It imports a Stylelint configuration and its ignore settings into your Biome configuration, mapping Stylelint rules to their Biome equivalents. Pass --write to apply the changes, and --include-inspired or --include-nursery to migrate additional rules.

  • #12318 774b5b5 Thanks @​Netail! - Added the new assist action useGraphqlSortedDefinitions, which sorts the named definitions of a GraphQL document, such as types, type extensions, directives, fragments, and operations.

    Invalid:

    type User {
      id: ID!
    }
    enum Role {
    ADMIN
    USER
    }
    directive @​auth on FIELD_DEFINITION

  • #6886 3479d15 Thanks @​christymcgrory! - biome rage now shows the resolved files.includes and files.ignoreUnknown configuration.

  • #11102 0874b7f Thanks @​gameroman! - Added support for useTailwindSortedClasses rule in HTML-ish files.

  • #10711 40de5a0 Thanks @​soconnor-seeq! - Adds a new resolutionKind option for object-syntax plugin entries.

    This allows shared Biome configs in monorepos to load local Grit plugins from the package that declares them instead of resolving plugin paths from the consuming project.

    {
      "plugins": [
        { "path": "./grit/no-debugger.grit", "resolutionKind": "config" },
        { "path": "local-plugin.grit", "resolutionKind": "project" },
        { "path": "local-plugin.grit" }
      ]
    }

    Use resolutionKind: "config" to resolve the plugin from the configuration file that declares it. Use resolutionKind: "project" to resolve the plugin from the consuming project. When omitted, resolutionKind defaults to project. This only affects plugin resolution; includes still apply to end-user project files as usual.

  • #11432 4befd08 Thanks @​ematipico! - Added biome inspect config to show resolved configuration values and their origins as human-readable diagnostics, including matching overrides.

    Configuration files can also extend other configurations up to ten levels deep. Repeated references to the same resolved file are ignored with an information diagnostic, while resolving multiple versions of one extended package produces an error.

... (truncated)

Changelog

Sourced from @​biomejs/biome's changelog.

2.6.2

Patch Changes

2.6.1

Patch Changes

Bumps the identifier group with 9 updates in the /identifier directory:

| Package | From | To |
| --- | --- | --- |
| [i18next](https://github.com/i18next/i18next) | `26.4.3` | `26.5.6` |
| [react](https://github.com/react/react/tree/HEAD/packages/react) | `19.3.0` | `19.3.1` |
| [react-dom](https://github.com/react/react/tree/HEAD/packages/react-dom) | `19.3.0` | `19.3.1` |
| [react-i18next](https://github.com/i18next/react-i18next) | `17.0.16` | `17.1.3` |
| [react-router](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router) | `8.4.0` | `8.5.0` |
| [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) | `2.5.15` | `2.6.2` |
| [@testing-library/user-event](https://github.com/testing-library/user-event) | `14.6.7` | `14.6.8` |
| [jsdom](https://github.com/jsdom/jsdom) | `30.0.1` | `30.1.3` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `8.3.4` | `8.3.5` |



Updates `i18next` from 26.4.3 to 26.5.6
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](i18next/i18next@v26.4.3...v26.5.6)

Updates `react` from 19.3.0 to 19.3.1
- [Release notes](https://github.com/react/react/releases)
- [Changelog](https://github.com/react/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/react/react/commits/v19.3.1/packages/react)

Updates `react-dom` from 19.3.0 to 19.3.1
- [Release notes](https://github.com/react/react/releases)
- [Changelog](https://github.com/react/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/react/react/commits/v19.3.1/packages/react-dom)

Updates `react-i18next` from 17.0.16 to 17.1.3
- [Changelog](https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md)
- [Commits](i18next/react-i18next@v17.0.16...v17.1.3)

Updates `react-router` from 8.4.0 to 8.5.0
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router@8.5.0/packages/react-router)

Updates `@biomejs/biome` from 2.5.15 to 2.6.2
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/@biomejs/biome@2.6.2/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.6.2/packages/@biomejs/biome)

Updates `@testing-library/user-event` from 14.6.7 to 14.6.8
- [Release notes](https://github.com/testing-library/user-event/releases)
- [Changelog](https://github.com/testing-library/user-event/blob/main/CHANGELOG.md)
- [Commits](testing-library/user-event@v14.6.7...v14.6.8)

Updates `jsdom` from 30.0.1 to 30.1.3
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Commits](jsdom/jsdom@v30.0.1...v30.1.3)

Updates `vite` from 8.3.4 to 8.3.5
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.3.5/packages/vite)

---
updated-dependencies:
- dependency-name: i18next
  dependency-version: 26.5.6
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: identifier
- dependency-name: react
  dependency-version: 19.3.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: identifier
- dependency-name: react-dom
  dependency-version: 19.3.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: identifier
- dependency-name: react-i18next
  dependency-version: 17.1.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: identifier
- dependency-name: react-router
  dependency-version: 8.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: identifier
- dependency-name: "@biomejs/biome"
  dependency-version: 2.6.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: identifier
- dependency-name: "@testing-library/user-event"
  dependency-version: 14.6.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: identifier
- dependency-name: jsdom
  dependency-version: 30.1.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: identifier
- dependency-name: vite
  dependency-version: 8.3.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: identifier
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file javascript Pull requests that update Javascript code labels Oct 26, 2026
@dependabot @github

dependabot Bot commented on behalf of github Nov 2, 2026

Copy link
Copy Markdown
Contributor Author

Looks like these dependencies are updatable in another way, so this is no longer needed.

@dependabot dependabot Bot closed this Nov 2, 2026
@dependabot
dependabot Bot deleted the dependabot/bun/identifier/identifier-61803249f8 branch November 2, 2026 08:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file javascript Pull requests that update Javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants