gilbsgilbs / babel-plugin-i18next-extract

Babel plugin that statically extracts i18next and react-i18next translation keys.
https://i18next-extract.netlify.com
MIT License
159 stars 37 forks source link

Trans is not extracted to namespace provided by t function (useTranslation) #153

Open mrkvon opened 4 years ago

mrkvon commented 4 years ago

Describe the bug

Context: We use babel-plugin-i18next-extract with react-i18next and react.

The translations from Trans components get extracted into default namespace even when t function from useTranslation('myNamespace') is provided in props. It should get extracted into myNamespace, not the default one.

How to reproduce

We want to extract a translation string from Trans component into a namespace provided by t function which we passed to Trans via props.

Babel configuration:

babel.config.js

const compact = require('lodash/compact');
const path = require('path');
const locales = require(path.resolve('./config/shared/locales'));

const isDevelopment = process.env.NODE_ENV === 'development';

module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        corejs: 2,
        modules: 'commonjs',
        useBuiltIns: 'usage',
      },
    ],
    ['@babel/preset-react'],
  ],
  plugins: compact([
    '@babel/plugin-proposal-nullish-coalescing-operator',
    '@babel/plugin-proposal-object-rest-spread',
    '@babel/plugin-proposal-optional-chaining',
    'angularjs-annotate',
    isDevelopment && 'react-refresh/babel',
  ]),
  env: {
    production: {
      plugins: [
        [
          // extraction of the i18next translation strings
          'i18next-extract',
          {
            nsSeparator: false,
            locales: locales.map(locale => locale.code),
            keySeparator: false,
            outputPath: 'public/locales/{{locale}}/{{ns}}.json',
            keyAsDefaultValue: ['en'],
            discardOldKeys: true,
          },
        ],
      ],
    },
  },
};

Reproduction:

The following example is based on documentation. More info is in related issue.

import React from 'react';
import { Trans, useTranslation } from 'react-i18next'

function MyComponent() {
  const { t } = useTranslation('myNamespace');

  // we provide namespace 'myNamespace' to Trans component
  // by passing t function as prop
  return <Trans t={t}>Hello World</Trans>;
}

Expected behavior

The translation string is extracted to the namespace provided by t (i.e. to public/locales/en/myNamespace.json)

What actually happens

The translation string is extracted to the default namespace (i.e. to public/locales/en/translation.json)

A workaround

The following works correctly: <Trans ns="myNamespace">Hello World</Trans>.

Your environment

gilbsgilbs commented 3 years ago

Hi, thanks for opening an issue. Yeah, trans component extraction doesn't parse "t" function at the moment. Don't think it's that easy to tackle though. It parses tOptions prop though if that's of help.