Skip to content

chore(deps): update i18next-cli to v1.80.4 - #3563

Merged
setchy merged 1 commit into
mainfrom
renovate/i18next-cli-1.x
Oct 29, 2026
Merged

setchy merged 1 commit into
mainfrom
renovate/i18next-cli-1.x

Conversation

@renovate

@renovate renovate Bot commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
i18next-cli 1.74.1 → 1.80.4 age confidence

Release Notes

i18next/i18next-cli (i18next-cli)

v1.80.4

Compare Source

  • fix(rename-key): calls with a string default value are renamed in the source. t('key', 'Default') and
    t('key', 'Default', { … }) were left untouched while the translation files were renamed, so the next extract
    brought the old key back. Moving such a key to another namespace keeps the default value:
    t('key', 'Default', { ns: 'ns2' }).
  • fix(extract): plural forms of a key stored flat stay flat in secondary locales. With "Loading..._one" in
    ru/translation.json, extract also wrote a nested copy, { "Loading": { "": { "": { "_one": … } } } }; the same
    happened for generated forms (_few, _many), preserved _zero forms, context variants and preservePatterns.
    A file that already has these nested copies loses them on the next extract.

v1.80.3

Compare Source

  • fix(rename-key): keys the extractor stores flat are renamed in the translation files. Renaming "Loading..." to
    "Saving..." left the old key in place and wrote { "Saving": { "": { "": { "": "Loading..." } } } }; renaming
    common.ok to "Okay, thanks." wrote { "Okay, thanks": { "": "OK" } }. The new key is now written where the next
    extract puts it (flat for "Loading...", natural-language and <Trans> keys), and the old key is removed however
    the file stores it. #​311

v1.80.2

Compare Source

  • fix(sync): flat keys that contain the key separator keep their translations. The extractor writes keys like
    "Loading..." or "Hello world. Bye" as one flat key, but sync split them on the separator, so a secondary file
    with { "Loading...": "Lädt..." } became { "Loading": { "": { "": { "": "" } } } } and the translation was lost.
    sync now writes them flat, and status, localize and rename-key find their values too. A secondary file
    already broken this way gets its flat key back (with an empty value) on the next sync.
    #​310
  • fix(types): placeholders with spaces on one side only ({{ name}}) are trimmed, and enableSelector no longer
    throws on plural keys whose base name is constructor, toString, … or also an object
    (i18next-resources-for-ts 2.1.2).

v1.80.1

Compare Source

  • fix(extract): a <Trans> interpolation variable named format is extracted. <Trans>Export as {{ format }}</Trans>
    was extracted as Export as , because react-i18next read format as the formatter name and dropped the variable;
    it is now Export as {{format}}, as react-i18next 17.1.8 renders it. Requires react-i18next ^17.1.8.
  • chore(deps): update dependencies within their ranges and neostandard to 0.14.

v1.80.0

Compare Source

  • feat(lint): in the i18next format, the translation files of every locale are compared with the primary language:
    interpolations by name ({{name}}, {{- name}}, {{val, number}}), nested $t(key) references and tags (<0>,
    <1/>, <bold>), except the basic HTML react-i18next keeps (transKeepBasicHtmlNodesFor). A translation that
    renamed or dropped a placeholder is reported with file, key and line, e.g.
    greeting: missing {{name}}, unexpected {{nom}} (compared with "en"). Plural forms are compared as a group, so
    {{count}} may be left out of _one or _zero. A warning by default, so existing CI runs keep passing;
    lint.checkTranslationPlaceholders: 'error' fails the run, 'off' disables it. Until now only ICU and MF2 projects
    had this check.
  • feat(status): values identical to the primary language (English copied into de) are marked
    ≈ (identical to en) and counted in the summary. status.checkIdentical: 'warn' (default) still counts them as
    translated and keeps the exit code, 'error' counts them as untranslated, 'off' disables it. Locales of the
    primary's language (en-GB with en), values without letters, URLs, e-mail addresses and short all-caps words
    (OK, FAQ) are skipped; other values that stay the same go into status.ignoreKeys.
  • feat(lint): lint --update-baseline writes the current issues to i18next-lint-baseline.json (lint.baseline for
    another path). While the file exists, lint reports and fails only on new issues, so a codebase with existing
    hardcoded strings can run lint in CI. Issues are matched by file, type and text, not by line.
  • fix(lint): interpolations are read like i18next does. The unescaped {{-name}} was read as a parameter -name, so
    t('Hi {{-name}}', { name }) reported two false interpolation issues; {{- name}} and names outside [A-Za-z0-9_.-]
    ({{größe}}) were not read at all.
  • docs(types): transKeepBasicHtmlNodesFor defaults to react-i18next's ['br', 'strong', 'i', 'p'].
  • docs(skill, localize): after translating by hand, run lint to check the placeholders.

v1.79.1

Compare Source

  • fix(init, migrate-config): the default source glob includes .mjs (src/**/*.{js,jsx,mjs,ts,tsx}), in init, in the
    config detected for a project without one, and in migrate-config when the old config has no input. Existing
    configs do not change. #​309

v1.79.0

Compare Source

  • feat(extract, instrument, lint): a .mjs file with JSX is parsed with the same JSX fallback as a .js file,
    including the constants pre-scan of extract. Before, it failed with a syntax error and extract exited with 1.
    #​309

v1.78.0

Compare Source

  • feat(lint): with messageFormat: 'mf2', lint warns when whitespace at the start or end of a pattern differs from
    the primary language. MF2 keeps a space inside {{ }} as text, so {{ {$count} files}} shows it in the app. A
    warning does not fail the run.
  • fix(lint): a language code with _ (ru_RU, pt_BR) is read as ru-RU, pt-BR for the plural categories. Before,
    Intl rejected it and only other was required, so a ru_RU plural with only one and other passed.
  • fix(lint): the required plural categories are other plus every category a whole number below one million selects
    (was 0 to 1000), the same rule as Locize; exact selectors count for a category only when it selects a few small
    numbers. No locale's result changes with today's CLDR data.
  • docs(skill): the ICU and MF2 reference names the common MF2 plural mistakes: other instead of *, {{ {$count}
    instead of {{{$count}, and spaces inside {{ }}.

v1.77.0

Compare Source

  • feat(types): with extract.messageFormat: 'icu' or 'mf2', a newly generated i18next.d.ts sets
    parseInterpolation: 'icu' or 'mf2' when the project's i18next is 26.5.0 or later, so t() options are type-checked
    against the arguments of each message. With i18next 26.2.0 to 26.4.x it still sets parseInterpolation: false. The
    version is read from node_modules/i18next/package.json, from the working directory upwards (hoisted monorepo
    installs count); without an installed i18next it stays false. The warning for an existing i18next.d.ts without
    parseInterpolation suggests the value for your i18next version, and an existing file that still sets false
    although your i18next supports the typed value gets a hint.
  • docs(skill): the ICU and MF2 reference describes parseInterpolation: 'icu' / 'mf2'.

v1.76.0

Compare Source

  • feat: new extract.messageFormat option, 'i18next' (default), 'icu' (i18next-icu)
    or 'mf2' (i18next-mf2), for the syntax of your translation values.
  • feat(extract): with messageFormat: 'icu' or 'mf2', extract writes one key per message. t('photos', '{count, plural, ...}', { count }) gave photos_one and photos_other (plus _few and _many for languages like Polish),
    keys i18next-icu and i18next-mf2 never read, and context gave _male keys; now it gives photos. $t() in a value
    is no longer read as nesting, and the children of <Trans> are written with {name} (ICU) or {$name} (MF2)
    instead of {{name}}, which ICU and MF2 rendered as text.
  • feat(extract): IcuTrans and IcuTransWithoutContext are extracted, also when imported under another name (key from
    i18nKey, or defaultTranslation when there is none), and so are the Trans, Plural, Select and SelectOrdinal
    components of react-i18next/icu.macro, with the message the macro builds (<Trans>Welcome, <strong>{name}</strong>!</Trans> gives Welcome, <0>{name}</0>!). Before, IcuTrans was
    not extracted, and the macro <Trans> was read as react-i18next Trans and written as
    Welcome, <strong>{{name}}</strong>!, which the compiled IcuTrans rendered as text.
  • feat(status): with messageFormat: 'icu' or 'mf2', a plural or select message counts as one key, so status no
    longer reports missing _few and _many keys.
  • feat(instrument): with messageFormat: 'icu' or 'mf2', instrument writes {name} / {$name} placeholders, a
    count === 1 ? … : … ternary becomes one plural message instead of defaultValue_one / defaultValue_other, and
    the i18n init file it creates registers i18next-icu (with intl-messageformat in the install hint) or i18next-mf2.
  • feat(extract, instrument): with messageFormat: 'icu' or 'mf2', the text around converted placeholders (Trans values, instrument) is
    escaped: File '{{name}}' not found becomes File ''{name}' not found, because an apostrophe before { starts quoted
    text in ICU and '{name}' would render as the text {name}; literal braces are quoted (ICU) or escaped (MF2).
  • feat(lint): with messageFormat: 'icu' or 'mf2', lint parses every value in the translation files of all
    locales and reports, with file, key and line (JSON files):
    • syntax errors with the parser's message (greeting: ICU syntax error: EXPECT_ARGUMENT_CLOSING_BRACE at column 7),
      with a hint when the value contains i18next's {{
    • argument names that differ from the primary language, so a renamed or missing {name} is caught (# is not an argument)
    • plural categories that do not fit the locale, for plural and selectordinal (MF2: .match on :number or
      :integer). Allowed are the locale's CLDR categories, required are other plus every category a whole number from
      0 to 1000 selects: ru needs one, few and many, while fr, es, it and pt may leave out many (only from
      1,000,000) and cs its many (fractions only), and zero in en is reported as never used. Exact selectors like
      =0 are allowed and count for a category when they cover every whole number it is used for (=1 covers one in
      en, not in ru, where one is also 21, 31, ...). For a locale Intl does not know only other is required.
  • fix(lint): with messageFormat: 'icu' or 'mf2', the t() interpolation check reads the arguments with the same
    parser. ICU braces like male {{name}} are no longer taken for {{name}} interpolation (which reported the gender
    passed to a select as unused), and t('greeting', 'Hello {name}', { nmae }) is reported.
  • feat(types): with messageFormat: 'icu' or 'mf2', a newly generated i18next.d.ts sets parseInterpolation: false
    (i18next 26.2.0+), so ICU and MF2 plurals no longer break the type-safe t. For an existing file without it, types
    prints a warning.
  • docs(skill): the i18next-localization skill has an ICU and MF2 section: which format to choose, setup, what silently
    stops working, IcuTrans, parseInterpolation: false and extract.messageFormat.
  • deps: @formatjs/icu-messageformat-parser (the parser i18next-icu uses through intl-messageformat) and messageformat
    (the MF2 implementation i18next-mf2 uses). They are only loaded when messageFormat is 'icu' or 'mf2'.

v1.75.3

Compare Source

  • fix(extract): options passed in a variable are read like inline ones. With const params = { count },
    t('key', params) now extracts the plural keys (and reads context, ns, defaultValue the same way),
    where it used to extract only key. A variable a file declares also no longer resolves to a same-named
    variable of another file: t('key', overwrittenParams) took y=true as its default value from an
    unrelated function-local overwrittenParams array elsewhere. Fixes
    #​307.

v1.75.2

Compare Source

  • fix(extract): declarations with the same name in different files no longer overwrite each other.
    Two generated OpenAPI clients that both export components resolved to whichever file was read first,
    so import { components as githubComponents } from './github-api' and
    import { components as digitalOceanComponents } from './digital-ocean-api' extracted the keys of only one
    of them, and moving files around changed which. A name now resolves to the module the file imports it
    from, for renamed and plain imports, namespace imports (GH.components), .js import specifiers and
    tsconfig paths aliases. Imports that cannot be traced to a scanned file (packages, re-exporting barrels)
    still resolve by name as before. Fixes #​306.

v1.75.1

Compare Source

  • fix(extract): types and values read through a namespace import resolve like named imports. With
    import * as Types from './types', a qualified type ((color: Types.Color) => …, x as Types.Color,
    FC<Types.Props>, declare const s: Types.Status) and a namespace member (Types.SIZES.map(…),
    Types.Status.Done, t(Types.LABELS.save), Object.keys(Types.LABELS)) now extract their keys, also
    for a namespace re-exported from a barrel (export * as Shared from './types'). Fixes
    #​305.
  • fix(extract): an exported as const object resolves in the files that import it: t(LABELS.save) and
    Object.keys(LABELS) only worked in the declaring file before.
  • fix(extract): a value typed keyof typeof MAP resolves to the map's keys, so
    t(`label.${key}`) with declare const key: keyof typeof LABELS extracts label.save and
    label.cancel. This branch never matched before.

v1.75.0

Compare Source

  • feat(extract): new extract.maxTypeDepth option sets how many levels of nested object members are
    followed when a dynamic key reads a typed value (default: 5). Higher values cost time and memory on
    large recursive types such as OpenAPI schemas. Requested in
    #​302.
  • fix(extract): the depth now counts from the type an indexed access picks instead of from the declared
    wrapper type. type Pet = components['schemas']['Pet'] gets the full depth below Pet, where the
    components/schemas wrapper used to take two of the five levels.
  • fix(extract): numeric keys resolve in object types and indexed access types, so openapi-typescript
    response types work:
    operations['getPet']['responses'][200]['content']['application/json'] and
    op.responses[200].content['application/json'].status resolved nothing before.

v1.74.8

Compare Source

  • fix(extract): a commented template literal no longer extracts its placeholder as a key.
    // t(`QUARTER.${q}`) extracted QUARTER.${q} and // t(`status.${deepObject.status}`) extracted
    status.${deepObject.status}. Such a comment now keeps the existing keys it matches (QUARTER.1,
    QUARTER.2, …) even with removeUnusedKeys, the way a commented static key keeps its key, while code can
    still add new matching keys. A pattern without any static part (`${a}.${b}`) is ignored. Fixes
    #​304.

v1.74.7

Compare Source

  • fix(extract): a selector i18nKey on <Trans t={t}> now routes into the hook's namespaces the same way
    t() does, matching react-i18next 17.0.16. With const { t } = useTranslation(['ns1', 'ns2']),
    <Trans t={t} i18nKey={$ => $.ns2.message} /> was filed as ns1:ns2.message; it is now filed as
    ns2:message, like t($ => $.ns2.message). Under types.enableSelector: 'strict' a leading primary
    namespace is stripped too (useTranslation('only') with $ => $.only.key files only:key). Reported in
    react-i18next#1933.
  • fix(extract): the props of a component typed React.FC<Props> (also FC, FunctionComponent),
    forwardRef<Ref, Props>(…) or memo<Props>(…) are typed by Props, and iterating a typed member binds
    the element. props.colors.map((color) => t(\Color.${color}`))withcolors: Color[]extracted nothing before unlesscolorwas asserted withas Color. Arrays of objects work the same way: props.items.map(({ kind }) => …), for (const item of props.items)and a destructured({ items }) => items.map(…)`. Fixes #​303.

v1.74.6

Compare Source

  • fix(extract): iterating an inline array literal binds the element like iterating a named constant
    does. ([1, 2, 3, 4] as const).map((q) => t(\QUARTER.${q}`)), for (const unit of ['day', 'hour'] as const)`
    and inline arrays of objects extracted nothing before. Fixes
    #​301.
  • fix(extract): members of nested object types resolve. t(\barStatus.${deepObject.Bar.status}`)andt(`fooBarStatus.${deepObject.Foo.Bar.status}`) now extract the nested union's values, also through references to other types, optional chaining (pet.category?.kind), destructuring (const { kind } = pet.category) and indexed access types (DeepObject['Bar']['status'], components['schemas']['Pet']), so types generated by openapi-typescript work. Nested members are followed up to five levels below the declared type, as in components.schemas.Pet.category.kind`.
    Fixes #​302.

v1.74.5

Compare Source

  • fix(extract): a value typed as an array of a string union (Color[], readonly Color[],
    Array<Color> or an alias of one) now resolves to the union's values, so
    colors.map((color) => t(\color.${color}`))andfor (const color of colors)extract every key instead of nothing. Before, this only worked withcolor as Color`. Fixes
    #​300.

v1.74.4

Compare Source

  • fix(extract): a conditional namespace argument resolves to the namespaces in its branches.
    useTranslation(confirmEmail ? ['reset-email-page', 'reset-page'] : 'reset-page') filed
    t('form.title') under defaultNS, so status reported it as absent and extract removed the
    existing translations from reset-page and reset-email-page. The key is now extracted into the
    primary namespace of every branch (here reset-email-page and reset-page), also for
    <Trans t={t}>. Fixes #​299.

v1.74.3

Compare Source

  • fix(extract): dynamic keys typed by a declaration in a file without any translation call
    resolve again when that declaration builds on one from a file that sorts after it. In 1.74.2,
    type Kind = Base | 'extra' in api/types.ts with Base declared in shared/base.ts expanded
    t(`kind.${kind}`) to kind.extra only, and the same happened to interface members,
    function return types and functions returning an enum member declared further down the list.
    Such declarations are now resolved again once every file has been scanned, which also removes
    the file-order dependence this had before 1.74.2.

  • feat(extract): more implicitly typed values expand to their finite set of keys. Fixes
    #​298:

    • members of an object returned by a function with an object return type:
      const animal = getAnimal(); t(`animal.${animal.type}`), also through
      const { type } = getAnimal(), const kind = animal.type or getAnimal().type.
    • unions and intersections of object types (type Animal = Duck | Dog gives animal.type the
      values of both) and generic object types (type AnimalBase<T extends AnimalType> = { type: T }
      used as AnimalBase<'DUCK'>, or bare, which falls back to the parameter's default or
      constraint).
    • (typeof COLOR)[keyof typeof COLOR] for an as const object or an enum.
    • elements of an array, colors[i], without an annotation on the variable they are assigned to.

    Narrowing is not followed: after if (color !== 'BLUE'), color.BLUE is still extracted.

  • fix(extract): shorthand options resolve like their long form. t('k', { ns }) filed the key
    under the default namespace, { defaultValue } was ignored and
    useTranslation('ns', { keyPrefix }) lost its prefix. Thanks to
    @​aaronshaf for reporting it in
    #​291.

v1.74.2

Compare Source

  • fix(extract): the output no longer depends on the order in which glob happens to return the
    input files. When two call sites give one key different defaults (t('k', 'Adding...') in one
    file, t('k', 'Importing...') in another), the first file visited wins, so an unchanged source
    tree could produce a different catalog from run to run and flip CI checks that compare against a
    committed catalog. Files are now visited in sorted path order, which makes the winner stable. If
    your sources contain such conflicts, the kept default may change once with this release. To
    hear about them instead of silently keeping one default, set
    extract.warnOnConflicts to 'warn' or 'error'. Fixes
    #​296.
  • perf(extract): files that contain no translation call, hook, TFunction, getFixedT or Trans
    component (as configured via functions, useTranslationNames and transComponents) are no
    longer parsed and walked a second time for keys. The constants pre-scan still reads every file,
    so types and as const values declared in such files keep resolving dynamic keys elsewhere.
    Plugins with an onVisitNode hook still see every file. On large trees where most files hold no
    translations this cuts extraction time considerably. Fixes
    #​297.
  • chore: update dependencies

Configuration

📅 Schedule: (UTC)

  • Branch creation
    • Between 12:00 AM and 03:59 AM, only on Monday (* 0-3 * * 1)
  • Automerge
    • At any time (no schedule defined)

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

♻ Rebasing: Whenever PR is behind base branch, 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 was generated by Mend Renovate. View the repository job log.

@renovate renovate Bot added the dependency Dependency updates label Oct 29, 2026
@renovate
renovate Bot force-pushed the renovate/i18next-cli-1.x branch 2 times, most recently from ef3f9bb to aa759d3 Compare October 29, 2026 10:25
@renovate
renovate Bot force-pushed the renovate/i18next-cli-1.x branch from aa759d3 to 8609ae2 Compare October 29, 2026 10:45
@setchy
setchy merged commit cf66642 into main Oct 29, 2026
15 checks passed
@setchy
setchy deleted the renovate/i18next-cli-1.x branch October 29, 2026 10:46
@github-actions github-actions Bot added this to the Release 8.0.0 milestone Oct 29, 2026
@sonarqubecloud

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in Gitify v8.0.0! 🎉

Downloads for macOS, Windows, and Linux are available on the release page.

Thanks for helping make Gitify better!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependency Dependency updates

Development

Successfully merging this pull request may close these issues.

1 participant