Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ICU extraction of plural in multiple languages produces invalid result #184

Open
jakubriedl opened this issue Mar 30, 2021 · 0 comments
Open

Comments

@jakubriedl
Copy link
Contributor

jakubriedl commented Mar 30, 2021

Describe the bug
When extracting multiple languages from Trans component with ICU, it produces invalid result for 2nd and latter language. See examples below.

How to reproduce
Run script yarn run babel 'src/**/*.tsx' with babel below and React component above

Babel configuration:

module.exports = {
  presets: ["@babel/preset-typescript"],
  plugins: [
    [
      "i18next-extract",
      {
        locales: ["en", "cs"],
        enableExperimentalIcu: true,
        outputPath: "locales/{{locale}}/{{ns}}.json",
        defaultNS: require(`${process.cwd()}/package.json`).name,
        useI18nextDefaultValue: true,
        discardOldKeys: true,
        customTransComponents: [
          ["react-i18next", "Trans"],
          ["react-i18next/icu.macro", "Trans"],
        ],
      },
    ],
  ],
}

Reproduction:

import { Trans } from "react-i18next/icu.macro"

export const Demo = () => {
  return (<Trans i18nKey="count-things" count={count}>{{count}} Thing</Trans>)
}

Expected behavior

{
  "count-things": "{count, plural, one {{count} Thing} other {{count} Thing}"
}

What actually happens

On second and latter language produces invalid result

{
  "count-things": "{count, plural, one {{count, plural, one {count} Thing} other {count} Thing}} other {{count, plural, one {count} Thing} other {count} Thing}}"
}

Your environment

  • OS (e.g. ArchLinux): OSX
  • Plugin version (e.g. 0.3.0): 0.8.2
  • Node version (e.g. 12.13.0): 14.15.4

Additional context

Why it happens: I tracked things down in the code and it is caused by the code in

const icuPlurals = pluralNumbersAsText
.map(
(numAsText: string) =>
`${numAsText} {${icuPluralValue(
extractedKey.parsedOptions.defaultValue,
)}}`,
)
.join(' ');
extractedKey.parsedOptions.defaultValue = `{count, plural, ${icuPlurals}`;
The reason is that the first run (language) sets the extractedKey.parsedOptions.defaultValue to the ICU formatted and the second run wrap that again and another again and so on. The fix can be to run this default value set only once and then use it for all languages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant