hang
hang

Reputation: 143

lingui library's macro t not working on react

I use the latest library for translation, but the macro t not working, the <Trans> working fine.

To Reproduce

  1. open codesandbox
  2. yarn install
  3. yarn start
  4. click different language on the top of screen

bug description:
only content in <Trans>content<Trans> will translated, but the last content on {hello react} not translated.

index.tsx:

import React from 'react';
import ReactDOM from 'react-dom/client';
import reportWebVitals from './reportWebVitals';
import { StoreProvider } from './components/store-provider';
import createStore from './store'
import { LanguageProvider } from './components/language-provider';
import { LangSwitcher } from './components/lang-switcher';
import { DataComponent } from './components/DataComponent';
import { Trans, t } from '@lingui/macro';

const store = createStore();

const root = ReactDOM.createRoot(
    document.getElementById('root') as HTMLElement
);
root.render(
    <React.StrictMode>
        <StoreProvider store={store}>
            <LanguageProvider>
                <LangSwitcher />
                <p>
                    <Trans>hello world</Trans>
                </p>
                <DataComponent data={t`hello react`} />
            </LanguageProvider>
        </StoreProvider>
    </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. 
reportWebVitals();

package.json:

{
  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@lingui/react": "^4.1.2",
    "@reduxjs/toolkit": "^1.9.5",
    "@testing-library/jest-dom": "^5.14.1",
    "@testing-library/react": "^13.0.0",
    "@testing-library/user-event": "^13.2.1",
    "@types/jest": "^27.0.1",
    "@types/node": "^16.7.13",
    "@types/react": "^18.0.0",
    "@types/react-dom": "^18.0.0",
    "make-plural": "^7.3.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-redux": "^8.0.5",
    "react-scripts": "5.0.1",
    "redux-persist": "^6.0.0",
    "redux-saga": "^1.2.3",
    "typescript": "^4.4.2",
    "web-vitals": "^2.1.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
        "extract": "lingui extract --clean",
    "compile": "lingui compile --strict"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@lingui/cli": "^4.1.2",
    "@lingui/macro": "^4.1.2"
  }
}

lingui.config.ts:

const linguiConfig = {
  catalogs: [
    {
      path: '<rootDir>/src/locales/{locale}/messages',
      include: ['<rootDir>/src'],
    },
  ],
  compileNamespace: 'cjs',
  fallbackLocales: {
    default: 'en-US',
  },
  format: 'po',
  formatOptions: {
    lineNumbers: false,
  },
  locales: [
    'en-US',
    'zh-CN',
    'zh-TW',
  ],
  orderBy: 'messageId',
  rootDir: '.',
  runtimeConfigModule: ['@lingui/core', 'i18n'],
  sourceLocale: 'en-US',
  pseudoLocale: 'pseudo',
}

export default linguiConfig

tsconfig.json:

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
        "baseUrl": "src"
  },
  "include": [
    "src"
  ]
}

Upvotes: 1

Views: 1465

Answers (1)

Andrii Bodnar
Andrii Bodnar

Reputation: 2202

Whenever you use the t macro in a React application, you should (1) "subscribe" your component to changes using the useLingui() hook, or (2) - use the defineMessage macro to define a message for later use. It has the same signature as t and returns a MessageDescriptor that you can pass to i18n._.

I would suggest modifying your code as follows:

index.tsx:

import React from "react";
import ReactDOM from "react-dom/client";
import reportWebVitals from "./reportWebVitals";
import { StoreProvider } from "./components/store-provider";
import createStore from "./store";
import { LanguageProvider } from "./components/language-provider";
import { LangSwitcher } from "./components/lang-switcher";
import { DataComponent } from "./components/DataComponent";
import { Trans } from "@lingui/macro";
import { msg } from "@lingui/macro";

const store = createStore();

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement
);
root.render(
  <React.StrictMode>
    <StoreProvider store={store}>
      <LanguageProvider>
        <LangSwitcher />
        <p>
          <Trans>hello world</Trans>
        </p>
        <DataComponent data={msg`hello react`} />
      </LanguageProvider>
    </StoreProvider>
  </React.StrictMode>
);

reportWebVitals();

DataComponent.tsx:

import { MessageDescriptor } from "@lingui/core";
import { useLingui } from "@lingui/react";

type props = {
  data: MessageDescriptor;
};

export const DataComponent: React.FC<props> = ({ data }) => {
  const { i18n } = useLingui();

  return <p>{i18n._(data)}</p>;
};

Tested in the sandbox and it works as expected.

Upvotes: 4

Related Questions