Use parent i18next with a React components library

Viewed 31

Some context

  • I have a mono repo with an app and a components library called ui.
  • The app is fetching translations from a remote server.
  • The ui lib uses the same translations as the app.

What I have tried

  • Inject the i18next via the I18nextProvider and use app translations inside the external library
  • It didn't work

Source

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;

Question

Is it possible to inject parent translation for the library components?

0 Answers
Related