Add i18next to a ReactJS project with dvajs

169 views Asked by At

I have a ReactJS project which uses dva (https://github.com/dvajs/dva, https://dvajs.com/API.html). I'm trying to add i18next to the project by following this youtube video. But it seems that i18next fails to be plugged into the project. As a consequence, loading the page localhost:8000/#/addin returns the following error. Could anyone help?

The above error occurred in the <withI18nextTranslation(Addin)> component:
    in withI18nextTranslation(Addin) (created by Connect(withI18nextTranslation(Addin)))
    in Connect(withI18nextTranslation(Addin)) (at router.tsx:79)
    in Route (at router.tsx:78)
    in Switch (at router.tsx:40)
    in Fe (at Theme/index.tsx:33)
    in Theme (at layouts/index.tsx:42)
    in BasicLayout (created by Route)
    in Route (created by withRouter(BasicLayout))
    in withRouter(BasicLayout) (at router.tsx:39)
    in Router (created by ConnectedRouter)
    in ConnectedRouter (at router.tsx:38)
    in AwaitPromiseThenRender (at router.tsx:34)
    in Provider (created by DvaRoot)
    in DvaRoot

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://.../react-error-boundaries to learn more about error boundaries.

Here are the code:

I first created src/i18n.js as shown in the video.

import i18next from "i18next";
import HttpBackend from "i18next-http-backend";
import LanguageDetector from "i18next-browser-languagedetector";
import { initReactI18next } from "react-i18next";

const apiKey = "1B4SDzcwnnNYK2ytKAiETw";
const loadPath = `https://api.i18nexus.com/project_resources/translations/{{lng}}/{{ns}}.json?api_key=${apiKey}`;

i18next
  .use(HttpBackend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    fallbackLng: "en",

    ns: ["default"],
    defaultNS: "default",

    supportedLngs: ["en","zh"],
    
    backend: {
      loadPath: loadPath
    }
  })

Then I modified src/index.tsx as follows by adding import './i18n.js' (I guess here it may be wrong):

import 'react-app-polyfill/ie11';
import 'react-app-polyfill/stable';

import dva from 'dva';
import './index.css';
import router from './router';
import AuthModel from './models/auth';
import SubscribtionModel from './models/subscription';
import AppModel from './models/app';
import { initializeIcons } from 'office-ui-fabric-react/lib/Icons';
import './i18n.js'

//@ts-ignore
//import createLoading from 'dva-loading';

initializeIcons();

// 1. Initialize
const app = dva();
//app.use(createLoading());

// 2. Plugins
// app.use({});

// 3. Model
//@ts-ignore
app.model(AuthModel);
app.model(SubscribtionModel)
app.model(AppModel);

// 4. Router
//@ts-ignore
app.router(router);

// 5. Start
app.start('#root');

In src/router.tsx, it is like follows:

import React from 'react';
import { routerRedux, Switch, Route } from 'dva/router';
import Layout from './layouts';
import { AwaitPromiseThenRender } from './components/AwaitPromiseThenRender';

const { ConnectedRouter } = routerRedux;
function RouterConfig({ history }: any) {
  //@ts-ignore
  return (
    <AwaitPromiseThenRender
      //@ts-ignore
      promise={typeof window.__$$notInOffice !== "undefined" ? Promise.resolve(true) : Office.onReady()}
    >
      <ConnectedRouter history={history}>
        <Layout>
          <Switch>
            <Route exact path="/addin">
              <Addin />
            </Route>
          </Switch>
        </Layout>
      </ConnectedRouter>
    </AwaitPromiseThenRender>
  );
}

export default RouterConfig;

In src/components/Addin/index.tsx, I have

import React, { lazy, ChangeEvent, useEffect } from 'react';
import { State as ReduxState } from '../../store/reducer';
import { connect } from 'dva';
import selectors from '../../selectors';
import { withTranslation } from 'react-i18next';

interface IProps {
  placeholder: string;
  app: string;
  uid: string;
  t: any;
}

interface IState {
}

class Addin extends React.Component<IProps, IState> {  
  render() {
    return (
      <div></div>
    );
  }
}

export default connect((state: ReduxState) => ({
  app: selectors.app.selectAppName(state),
  uid: selectors.auth.getUid(state)
}))(withTranslation()(Addin));

Does anyone know what's the correct way to plug i18next (with i18next-http-backend) into this project?

0

There are 0 answers