gilbsgilbs/babel-plugin-i18next-extract

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

mrkvon opened this issue · 1 comments

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

  • OS: Arch Linux
  • Plugin version (e.g. 0.3.0): 0.7.2
  • Node version (e.g. 12.13.0): 13.12.0

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.