npm / i18next-cli
i18next-cli
What changed in i18next-cli 1, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-25.
30 breaking1 security55 new APIs and options2 performance36 behavior and defaults12 tooling118 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli initi18next-cli 1254 changes
Breaking changes 30
Plural forms of flat keys stay flat in secondary locales; existing nested copies are removed on the next extract.
Spaces on one side of placeholders such as
{{ name}}are trimmed.A <Trans> interpolation variable named format is extracted as {{format}} instead of being dropped. Requires react-i18next ^17.1.8.
Lint interprets language codes containing underscores as hyphenated codes when determining required plural categories.
Lint requires
otherand every category selected by whole numbers below one million; exact selectors count only when they select a few small numbers.With ICU or MF2, text around converted placeholders is escaped, and literal braces are quoted or escaped for the selected format.
Depth now counts from the type selected by an indexed access, rather than from its declared wrapper type.
Commented template literals no longer extract placeholders as keys; matching existing keys are kept even with removeUnusedKeys, while patterns without a static part are ignored.
The shorthand ns option now resolves like its long form instead of filing the key under the default namespace.
Files are visited in sorted path order, so conflicting defaults resolve consistently and unchanged source trees produce stable catalogs. The kept default may change once if sources contain conflicts.
Named type aliases are no longer resolved to their first member, avoiding arbitrary namespace attribution for app-wide unions.
Calls to t() inside fenced code blocks in doc comments are no longer extracted as real call sites.
status and extract now resolve useTranslation calls with a dynamic namespace and a literal ?? or || fallback to the statically known fallback namespace instead of defaultNS.
When false, the generated i18next.d.ts derives the default namespace from generated resources, avoiding types that silently accept any string. Locale-named resource files still emit false.
Lint detection now flags any two or more adjacent translation units rendered as direct siblings, including adjacent <Trans> components and {t(...)} expressions.
Adds a default-enabled lint check for translated-string concatenation in JavaScript and sentences split across multiple <Trans> components; set false to disable it.
When a locale is requested, the pass/fail result is based only on that locale; primary locales fail only on absent keys, while secondary locales fail on any untranslated or absent key.
The option now accepts true or false, allowing you to sync all languages with --src-lng-only false; omitting it preserves locize-cli's true default.
The status command now checks the primary language and reports missing keys with a non-zero exit code; empty-string placeholders count as present.
The directive now suppresses the entire following JSX element, including nested children, in both lint and instrument commands.
Unparseable JSON/JSON5/YAML files that exist on disk now throw instead of returning null, stopping the command before it can overwrite their contents; .ts/.js resource files remain lenient.
Scoped i18n method calls that do not match a configured function pattern are no longer extracted as translation keys; matching calls still inherit namespace and keyPrefix scope.
The <Trans> bare-identifier diagnostic now uses logger.error and is prefixed with Error:, allowing build tooling to treat it as fatal.
Detects hardcoded strings in JSX expression containers, applying the same acceptance and ignore rules as raw text.
When nsSeparator is false, the merged-path loop treats any defaultNS-keyed bucket as top-level, including keys from useTranslation() with no arguments.
Files with unsupported extensions that no plugin handles are silently skipped instead of throwing an ExtractorError.
Nesting conflicts are now reported as errors instead of silently skipping the key.
The extractor should fail on error, so extraction errors are no longer silently tolerated.
When a config file exists but fails to load, the CLI exits with a non-zero code instead of prompting to create a new one.
Interpolation lint checks the translated value, not just the key, when key and value differ.
Security 1
Potential API-key output is masked for the locize command, reducing the risk of exposing keys in console output.
New APIs and options 55
Writes current lint issues to a baseline so lint reports and fails only on new issues while the file exists.
Sets an alternate path for the lint baseline file.
Compares i18next translation placeholders, nested references and tags across locales; set to 'error' to fail or 'off' to disable the check.
Controls how values identical to the primary language are counted and whether they trigger a warning or are ignored.
Selects the translation value syntax: i18next by default, or ICU or MF2.
Sets how many levels of nested object members are followed when a dynamic key reads a typed value; defaults to 5.
Offers to append an Internationalization section to AGENTS.md and, when present, CLAUDE.md; no files are written unless the developer agrees. Use --no-agent-note to skip the question.
Supplies the Locize project id and skips the signup page and credential prompts; LOCIZE_PROJECTID can supply the same value.
Runs init without the wizard and uses detected defaults for questions not answered by the supplied options, enabling scripted setup.
Syncs and AI-auto-translates only keys changed on the current Git branch versus the base branch; deletions are skipped and changed plural keys include all plural forms.
Configures changed-only syncing for locize.
Sets the base branch for changed-only locize syncing.
Propagates only primary-language keys added or modified on the branch to secondary language files; obsolete keys are left in place. Supports JSON, JSON5 and YAML files.
Adds glob patterns for keys that status should not report or fail on; extract is unchanged.
Set acceptedTags to 'all' to lint every JSX tag, including custom components; ignoredTags and transComponents still take precedence, and the unset default is unchanged.
Adds --unused to report translation keys that are no longer used in source code. The command does not modify files and exits non-zero when unused keys are found or source files fail to parse.
Adds an opt-in lint check that flags punctuation glued onto a translation; it accepts the same values as checkConcatenation and defaults to 'off'.
Accepts severity levels: 'error' makes the lint command exit non-zero, 'warn' reports non-failing warnings, and 'off' disables the check. Boolean values remain supported.
Lint issues can carry an optional severity of 'error' or 'warning'; plugins may set it, and omitted severity defaults to 'error'.
Adds the
locizesort preset, matching locize-published key order so extract followed by locize-sync/locize-download avoids spurious reorder diffs.The init wizard can scaffold an inlang project with project.inlang/settings.json derived from i18next configuration and recommend the Sherlock VS Code extension; existing settings are not overwritten.
A new supercommand orchestrates detection, configuration, instrumentation, extraction, Locize setup and sync, then downloads asynchronous translations. It is safe to re-run.
Adds a CDN type option supporting standard and pro.
Adds CI mode, which skips instrumentation unless combined with --yes.
Adds a dry-run flag to the localize command.
Adds a namespace option to the localize command.
Prints a copy-paste prompt for AI coding agents to perform the same steps via individual CLI commands.
Adds a flag to skip instrumentation.
Adds a flag to skip Locize setup.
Adds a flag to skip translation.
Adds an update-values flag to the localize command.
Adds a yes flag to the localize command.
Adds a pass-through flag to enable or disable automatic translation.
Adds a pass-through flag to select languages for automatic translation.
Adds a pass-through flag to configure automatic translation review.
Adds a configuration option for staging or self-hosted Locize API endpoints.
Adds a configuration option for automatic translation.
Adds a configuration option for selecting automatic translation languages.
Adds a configuration option for automatic translation review.
The localize flow is also available for programmatic use.
Setting this option to false lets you sync all languages instead of only the source language.
The types command can use --ci to compare generated TypeScript definitions with files on disk without writing, exiting non-zero when they are out of date. It cannot be combined with --watch.
The --with-types flag regenerates TypeScript definitions in the same process after extraction when translation files change, avoiding two parallel watch processes.
The init wizard now asks which translation backend to use, offering local files, Locize, or other/skip.
Choosing Locize opens its signup page, prompts for a Project ID and optional API key, and writes a
locizeblock matching the shape consumed by Locize commands.Accepts 'strict', applying leading-namespace rewrites uniformly across hook scopes and emitting enableSelector: "strict" in generated i18next.d.ts.
Adds the locale field to the TranslationResult object passed to the afterSync plugin hook, so plugins no longer need to reverse-engineer this value from the file path.
Adds the namespace field to the TranslationResult object passed to the afterSync plugin hook, so plugins no longer need to reverse-engineer this value from the file path.
Optionally derive TypeScript namespaces from paths relative to types.basePath, enabling nested namespaces; omitting it preserves existing behavior.
Adds an opt-in flag that trusts default values inferred from keys, including plain key-as-text usage and keyPrefix-derived values, while preserving strict sync behavior by default.
Set to true to generate all six CLDR plural forms for every language, including the primary language, for a consistent set of keys across locales.
Adds a plugin hook to observe every key extraction before deduplication.
Adds an option to detect conflicting default values for the same key;
trueor'warn'logs, while'error'throws.Adds a command that wraps hardcoded strings with t(), injects useTranslation() hooks in React components, generates an i18n init file, and imports it into the project's entry point.
Adds hideTranslated to show only untranslated keys in the detail status view.
Performance 2
Files without translation-related calls or components are no longer parsed and walked a second time for keys, reducing extraction time on large trees while preserving constants pre-scan behavior.
The extract command no longer scales quadratically with the number of keys; a 4-minute run on a ~11,500-key monorepo drops to seconds, with byte-identical output.
Behavior and default changes 36
The default source glob now includes .mjs for init, detected configs without one, and migrate-config when the old config has no input; existing configs are unchanged.
With MF2, lint warns when pattern whitespace at the start or end differs from the primary language; the warning does not fail the run.
With ICU or MF2, extraction writes one key per message, avoids treating
$t()as nesting, and uses format-appropriate placeholders in<Trans>children.With ICU or MF2, plural and select messages count as one key, so status no longer reports missing plural-suffix keys.
More implicitly typed values expand to their finite set of keys, including object members, unions and intersections, generic object types, const-object or enum values, and array elements.
The default ignore for node_modules is dropped when an extract.input pattern mentions it, allowing dependency declarations or package sources to be resolved or extracted.
The skill no longer presumes Locize; it asks the developer whether to manage translations with Locize or keep files in the repository.
The agent prompt asks whether to use Locize or keep translation files in the repository, and only creates a Locize project or requests an API key if Locize is chosen. It creates config with init --yes instead of the wizard.
The help output now ends with a one-line hint for installing the i18next-localization Agent Skill.
After status, extract, and sync, the hint is now a single line naming the untranslated-key gap and the command to fill it; it appears only when secondary locales have untranslated keys.
status now warns when a fallback namespace listed in ignoreNamespaces has translations that cannot be found, rather than silently reporting keys as absent.
Resolves finite string-literal unions through iterated array element types, expanding template translation keys for supported array methods.
Instrumentation now leaves module-scope string candidates untouched and reports a warning pointing to the hook alternative; strings inside plain functions are still instrumented.
Concatenation issues are warnings and do not fail the run; the lint command exits non-zero only when there are errors.
Locize funnel/tip messages are suppressed when CI=true or stdout is not a TTY, and the once-per-24h cooldown applies even when translation files are newly created.
fallbackNS accepts an array of namespaces, looked up in order; this is supported by extract, status, and the TypeScript types generator.
Trailing wildcards now match any method on an object, and are also honored by the linter and rename-key.
Automatic translation is enabled by default for new Locize projects and only runs when the reference language is updated; translation happens asynchronously on the Locize side.
Maps the project-not-found sync error for projects without languages to guidance to update locize-cli or add languages in project settings.
Locize commands now resolve credentials from environment variables after CLI options and the locize config block, then forward them as explicit flags, avoiding stale ~/.locize settings redirecting operations.
During the first sync, languages from configuration are created automatically; target languages need not be added in the UI, and any write-capable key works.
When enabled, context variants from the primary locale are copied to every secondary locale as empty placeholders, while existing secondary values remain untouched.
The translation report now includes context variants found in the primary translation file for base keys used with a dynamic context value.
Prints a per-file diff of added, removed, and changed keys when CI fails because files would be updated, making failures actionable without reproducing them locally.
Infers function return types from function bodies when no explicit annotation is present, including across files, so statically resolvable values can be extracted as keys.
A warning is emitted when types.basePath is misconfigured and translation files fall outside the specified base directory.
The default useTranslationNames now includes getT and useT, so keys from next-i18next v16 App Router hooks are extracted into the specified namespace instead of defaultNS.
The status output distinguishes untranslated keys (present with an empty value) from absent keys (missing entirely); both still cause a non-zero exit.
A warning is emitted when an explicitly listed non-native extension is not handled by a plugin, helping catch forgotten or misconfigured plugins.
The extractor captures as const array literals and expands their values when used in .map() or .forEach() callbacks.
Exported as const arrays and type aliases are shared across files, enabling resolution of imported constants and type aliases.
The extractor resolves namespaces from const and identifier expressions without custom plugins.
The extractor handles object props as namespaces.
Locize CLI calls now fall back to npx.
locize-migrate now internally always uses --download true.
The interactive prompt was improved for the locize command.
Tooling 12
Generated i18next.d.ts now selects the typed ICU or MF2 parseInterpolation value based on the installed i18next version; warnings and hints for existing files also reflect the supported value.
With ICU or MF2, writes format-appropriate placeholders, converts count ternaries into one plural message, and registers the matching plugin in the generated i18n init file.
With ICU or MF2, parses translation values across locales and reports syntax errors, argument mismatches, and plural categories that do not fit the locale.
With ICU or MF2, newly generated declarations set
parseInterpolation: falsefor i18next 26.2.0+;typeswarns if an existing file lacks it.Extraction now uses typed component props and binds typed array members in iteration, so translation keys in map callbacks, loops, and destructured props are extracted.
Finite dynamic keys now resolve through renaming imports, including type aliases, enums, interfaces, as-const arrays, and helper functions.
React is no longer a runtime dependency; the CLI resolves React from the consuming project through react-i18next, avoiding a nested duplicate copy.
extract now warns when a <Trans> component contains a bare identifier JSX child and points users to the {{cat}} form with a values prop.
Generated type files use a combined default interface declaration and a type-only import, making them compatible with TypeScript's verbatimModuleSyntax option without changing the interface's type identity.
Plugins can return transformed JS/TS code for any file type, including .svelte and .vue, and the extractor parses it using TSX syntax.
The extractor improves TS type-aware resolution for finite dynamic keys, including template unions, const maps, and helper returns.
Adds a linter plugin to i18next-cli.
Fixes and other changes 118
rename-key now renames calls with a string default value, and moving a key to another namespace keeps the default value.
Renaming flat keys now writes the new key where the next extract would put it and removes the old key regardless of how the file stores it.
No longer throws on plural keys whose base name is
constructor,toString, or another such name, or is also an object.Keys containing the key separator stay flat during sync, preserving translations; status, localize and rename-key also find their values.
Interpolation parsing now matches i18next behavior for unescaped placeholders and names outside the previous character set, avoiding false or missed interpolation issues.
Files with JSX are parsed with the same JSX fallback as .js files in extract, instrument, and lint; extract also includes them in its constants pre-scan.
With ICU or MF2, the
t()interpolation check uses the same parser, avoiding false interpolation reports and catching misspelled arguments.Extracts
IcuTransandIcuTransWithoutContext, including when imported under another name, usingi18nKeyordefaultTranslationas the key.Extracts its
Trans,Plural,SelectandSelectOrdinalcomponents using the message built by the macro.Options passed through a variable are read like inline options during extraction, including plural keys, context, ns, and defaultValue; variables are resolved within their own file.
Declarations with the same name in different files now resolve to the module the file imports them from, preventing extraction from depending on file order.
Extraction now resolves imported references to an exported as const object, including t(LABELS.save) and Object.keys(LABELS).
Extraction now resolves values typed as keyof typeof MAP to the map's keys, enabling template keys such as label.save and label.cancel.
Extraction now resolves types and values accessed through namespace imports, including namespaces re-exported from a barrel.
Numeric keys now resolve in object types and indexed access types, enabling extraction from openapi-typescript response types.
Selector i18nKey values on <Trans t={t}> now route into the hook's namespaces like t() does, preventing duplicated namespaces during extraction.
Extraction now binds elements when iterating inline array literals, so translation keys using those elements are extracted.
Extraction resolves nested object type members, including through references, optional chaining, destructuring, and indexed access types, up to five levels below the declared type.
Values typed as arrays of a string union now resolve to the union's values, allowing extraction of every key in map and for-of usage without a type assertion.
Conditional namespace arguments now resolve to the namespaces in their branches, so extracted keys are filed in each branch’s primary namespace, including for <Trans t={t}>.
Dynamic keys declared in files without translation calls are resolved after all files have been scanned, removing file-order dependence.
The shorthand defaultValue option is no longer ignored.
The shorthand keyPrefix option now resolves like its long form instead of being lost.
Extraction no longer drops keys, plural forms, default values, key arrays, selectors, or option values when they are wrapped in parentheses.
The extractor now statically resolves non-string-literal default values from module-scope consts, object maps, or enums instead of dropping them; ambiguous expressions still fall back to the key.
Object literals in as const arrays are now captured, resolving destructured properties in for...of loops and forEach callbacks.
Dynamic keys built from for...of loop variables are now extracted because the loop variable is bound while the loop body is walked.
Destructuring a known as const object now resolves its property for dynamic keys.
The interactive instrument prompt now uses Inquirer’s select prompt type instead of the removed list type, preventing a crash.
status and extract now find a fallback namespace at its per-namespace path when it is missing from a merged file, supporting hybrid layouts.
A function output resolves the merged file without a namespace, matching what extract writes and allowing hybrid layouts.
.reduce()and.reduceRight()over anas constarray now bind the element callback parameter, allowing extraction without a(typeof ERRORS)[number]cast.When ns is a function parameter, it resolves to its string default or, without a default, the first member of its inline union type.
TFunction members are now found inside intersection types, including optional t properties and overload implementation signatures.
Namespace detection now resolves union, generic, and local type aliases for TFunction, and local const arrays for useTranslation, like inline arrays.
A local wrapper forwarding its first parameter as the key to a scoped translation function inherits that function's namespace and keyPrefix.
Parameters typed as ReturnType<typeof useTranslation<'ns', 'keyPrefix'>>['t'] are treated like TFunction<'ns', 'keyPrefix'> for namespace detection.
status and extract now honor TFunction namespace and key-prefix types on destructured parameters, including types supplied through a local interface or type alias.
Accepts FunctionBody nodes from @swc/core 1.16, restoring selector calls with block bodies, return-type inference from function bodies, and React component-boundary detection for useTranslation() and <Trans> injection.
Lint reports hardcoded strings at the line indicated by the AST node span, fixing incorrect line numbers and allowing line-based ignore directives to suppress the intended issues.
Key sorting is now transitive, making extract idempotent and preventing key order from flipping across extract/download cycles.
The generated import is inserted after the preceding import’s line, with a leading newline when that import ends at EOF without one.
Directories whose names match input globs no longer abort the run with EISDIR.
Corrects line and column locations for files containing multi-byte characters; the span-base correction also fixes locations in files with leading multi-byte comments for the linter and instrumenter.
Extraction now expands keys for finite string-literal unions that reach a key through interface- or object-typed function parameters, including destructured, renamed, defaulted, and member-accessed values.
Extraction now ignores <Trans> components without an i18nKey expression or non-whitespace children, preventing an empty-string translation key.
ConsoleLogger.error no longer swallows its optional second argument, so plugin-hook failures print the caught error instead of a bare message.
ConsoleLogger.warn no longer swallows its optional second argument, so plugin-hook failures print the caught error instead of a bare message.
Extraction now attributes keys found in fallback namespaces there, preserving them from removeUnusedKeys; non-empty values in the requesting namespace remain intentional overrides, and empty placeholders are cleaned up.
A scoped failure message now names the requested locale, making the reason for failure clear.
When
disablePluralsis true, a key used withcountis satisfied by either its plural variants or the bare key, matching the runtime resolution chain.Plural categories reachable only for out-of-range values are treated as optional, so missing or empty variants no longer fail the check; categories reachable by typical counts remain required.
The command now pins @inlang/plugin-i18next@6.2.1, restoring Sherlock inline annotations, hovers, and message extraction for i18next projects.
The CJS build now uses automatic interop to unwrap default exports at runtime, fixing crashes in spinner-using commands with ESM-only dependencies.
Declared as a direct dependency at ^26.3.0, matching react-i18next's peer requirement so package managers that don't auto-install peers get a compatible copy.
Loaded lazily and defensively only when serializing <Trans> children, so incompatible versions no longer crash unrelated CLI commands and Trans serialization degrades gracefully with a warning.
instrument no longer breaks multi-line imports when injecting the useTranslation import.
The types command now accepts .yaml, .yml, and .json5 input files, avoiding SyntaxError when using these translation sources.
types --watch uses chokidar's awaitWriteFinish option, preventing mid-write triggers when another process rewrites translation files.
For multi-namespace useTranslation hooks, selector paths beginning with a secondary namespace are routed to that namespace's file; primary-prefixed paths and single-namespace hooks are unaffected.
For multi-namespace useTranslation hooks, selector paths beginning with a secondary namespace are routed to that namespace's file; primary-prefixed paths and single-namespace hooks are unaffected.
lint now sets type to hardcoded on hardcoded-string issues, so consumers can reliably distinguish them with issue.type === 'hardcoded'.
Propagates namespace and keyPrefix from useTranslationNames-listed calls stored on class fields and later destructured in methods, so translated keys are extracted with the correct namespace.
With --sync-primary, <Trans> defaults now update for keys containing an underscore that are not plural or context variants.
With --sync-all --trust-derived, locale-specific plural variants are preserved instead of being cleared when absent from the primary locale.
Extraction now walks both branches of ternary and short-circuit logical selector bodies, preserving referenced keys instead of pruning them.
The bare-identifier diagnostic now points only to the
{{x}}+values={{ x }}fix, removing a misleading suggestion to inline the value.extract now resolves constant identifiers passed as the namespace or keyPrefix argument, using the same resolution logic as useTranslation.
status now includes keys referenced only through nested $t(...) references in the primary translation file, including plural and context variants, so translation gaps in secondary locales are reported.
When enabled, keys referenced through $t(...) in existing translation values are preserved, including plural and context variants; secondary locales receive the correct CLDR plural skeleton on first extract.
Propagates defaultNs and keyPrefix from custom translation hooks to inner t() calls accessed via a member expression, preventing keys from falling back to the default namespace.
Secondary locale translations are no longer cleared for explicit defaults when the code-provided default still matches the primary locale value.
Selector API extraction now resolves dynamic bracket expressions and captures function parameter type annotations, preventing possible keys from being incorrectly treated as unused and removed.
With --sync-all --trust-derived, secondary locale values are cleared only when syncing would actually update the primary locale.
Fixes repeated runs producing different results for keys with derived default values, preventing the primary locale from being unexpectedly rewritten.
Dynamic bracket expressions in the selector API are resolved into all possible keys, preventing valid keys from being treated as unused and removed during extraction.
Fixes --sync-all not clearing secondary locale translations when mergeNamespaces is enabled.
The extractor now uses the full enum type when a variable has both a type annotation and an initializer, extracting all enum values.
Now correctly preserves HTML tag names when children contain interpolations or mixed content.
Directories with file-like extensions are silently skipped instead of producing a misleading warning.
With nsSeparator: false and multiple namespaces, default namespace keys are now kept under translation instead of being placed at the top level.
Plural forms are now limited to the union of CLDR categories needed by configured locales, rather than always generating all six forms.
defaultValues are now applied consistently to extra plural forms.
Unrecognized custom locale codes now fall back to English plural rules instead of throwing a RangeError.
With nsSeparator: false, implicit-namespace keys in a merged single-file layout are routed to the top level instead of being wrapped under defaultNS.
When removeUnusedKeys: true, sort: false preserves the existing key order and appends new keys at the end.
The extract and sync commands silence all non-essential output in quiet mode, including promotional messages.
Namespaces containing spaces are no longer rejected by the natural-language heuristic when explicitly provided; the check applies only to namespaces derived by splitting a key string.
The TypeScript signature now allows returning undefined to opt out of transformation, matching the intended pattern.
Fixes inconsistent plural key ordering in JSON locale files produced by sync and extract --ci.
Sync no longer clears locale-specific plural forms such as _many in secondary locales, preventing status from reporting missing translations.
The extractor improves namespace resolution from const and identifier expressions.
Fixes the disablePlurals flag being ignored when extracting languages.
Imports in d.ts files now include file extensions.
The extractor now resolves the namespace when ns is a const variable, matching the existing useTranslation(IDENTIFIER) behavior.
Type aliases referenced by declare const and useState destructuring patterns now resolve after the alias is captured, fixing ordering-dependent failures.
Indexed access types now resolve correctly through TsParenthesizedType wrappers emitted by SWC.
The extractor resolves and safely handles constants across files.
The extractor handles typed expressions.
The instrumenter was improved regarding the i18n init file.
The instrumenter was improved regarding the Trans component.
Fixes false positives when checkInterpolationParams encounters variable t() options.
Prefixes the nesting conflict message.
checkInterpolationParams now supports interpolation parameters using the {{param, format}} syntax.
Fixed expanded plurals losing location information.
Fixed extraction with keySeparator creating empty string segments.
Extraction now uses the inline count property of the Trans component.
Fixes Identifier handling in the getObjectPropValue utility.
Fixes insufficient evaluation of namespace and keyPrefix scope.
Interpolation lint reports the correct line number for each duplicate t() call.
Reverts the overly greedy multi-segment namespace glob behavior that matched unrelated locale files and could overwrite existing translations with empty objects.
The linter checkInterpolationParams now ignores i18next variables.
The extractor now respects ignoreNamespaces when removeUnusedKeys is true.
Fixed handling of multi-segment namespaces when matching output paths and recovering namespace paths.
Corrects the base offset for files with leading whitespace or comments because Module.span.start points to the first token, not byte 0.
Span offsets in onVisitNode are now file-relative instead of accumulating across files, so spans stay within the source file length.
The linter improves checkInterpolationParams handling when an object is used as a value.
Fixes extractor serialization of <Trans> when the project and CLI use different React versions, such as React 18.