reactjs - Använd förälderns i18next med ett React-komponentbibliotek


Lite sammanhang

  • Jag har ett monorepo med en app och ett komponentbibliotek som heter ui.
  • app hämtar översättningar från en fjärrserver.
  • ui-biblioteket använder samma översättningar som app.

Vad jag har försökt

  • Injicera i18next via I18nextProvider och använd appöversättningar i det externa biblioteket
  • Det fungerade inte

Källa

app/package.json
{
  "name": "app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@types/react": "^17.0.43",
    "@types/react-dom": "^17.0.14",
    "i18next": "^21.6.14",
    "i18next-browser-languagedetector": "^6.1.4",
    "i18next-http-backend": "^1.4.0",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-i18next": "^11.16.2",
    "ui": "*"
  },
  ...
}
app/index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { I18nextProvider } from 'react-i18next';
import i18n from './services/i18n';

ReactDOM.render(
  <React.StrictMode>
    <React.Suspense fallback={'Loading'}>
      <I18nextProvider i18n={i18n}>
        <App />
      </I18nextProvider>
    </React.Suspense>
  </React.StrictMode>,
  document.getElementById('root'),
);
app/services/index.tsx
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import Backend from 'i18next-http-backend';
import { Http } from 'api';

i18n
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init(
    {
      debug: false,
      react: {
        useSuspense: true,
      },
      backend: {
        loadPath: `${Http.baseUrl}/language/{{lng}}`,
        allowMultiLoading: false,
      },
      lng: 'en',
      fallbackLng: ['en', 'lt'],
      saveMissing: true,
      interpolation: {
        escapeValue: false,
        formatSeparator: ','
      },
    }
  );

export default i18n;
app/layout/index.tsx
import React  from 'react';
import { I18nextProvider, useTranslation } from 'react-i18next';
import i18n from 'services/i18n';
import { Temp } from 'ui';

const Layout: React.FC = () => {

  const { t } = useTranslation();

  return (
    <>
      <I18nextProvider i18n={i18n}> {'<- NOT INJECTING'}
        <Temp />
      </I18nextProvider>
    </>
  );
};
export default Layout;

ui/package.json
{
  "name": "ui",
  "version": "0.0.0",
  "main": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "sideEffects": false,
  "private": true,
  "scripts": {
    "build": "tsup",
    "clean": "rm -rf dist",
    "dev": "tsup --watch",
    "lint": "eslint src/*.ts*"
  },
  "files": [
    "dist",
    "src"
  ],
  "dependencies": {
    "@types/react": "^17.0.43",
    "@types/react-dom": "^17.0.14",
    "i18next": "^21.6.14",
    "i18next-browser-languagedetector": "^6.1.4",
    "i18next-http-backend": "^1.4.0",
    "typescript": "^4.6.3",
    "react": "^17.0.2"
  },
  "devDependencies": {
    "tsup": "^5.10.1"
  },
  "tsup": {
    "clean": true,
    "dts": true,
    "external": [
      "react"
    ],
    "format": [
      "cjs"
    ],
    "entryPoints": [
      "src/index.tsx"
    ],
    "loader": {
      ".svg": "dataurl"
    }
  }
}
ui/components/temp/index.tsx
import React, { useEffect } from 'react';
import { useTranslation } from 'react-i18next';

const Temp: React.FC = () => {
  const { t, i18n } = useTranslation();
  return <div>{t('sidebar.clients')}</div>;
};

export default Temp;

Fråga

Är det möjligt att injicera föräldraöversättning för bibliotekskomponenterna?

Svar #1

Med den senaste versionen returnerar 1i8n ett löfte, för att få det att fungera exportera om i18n från app/services/index.tsx och det borde fungera bra då