react-i18next: Can't find a way to make it work, error with 'options' or 'getFixedT'

Hi,

I’m trying to configure i18next with my React project and I can’t make it work at all…

Whatever I try, I get either this :

TypeError: Cannot read property 'options' of undefined
    at new Translate (/Users/ank49/Documents/React Projects/Portfolio React i18n/node_modules/react-i18next/dist/commonjs/translate.js:65:32)

or this :

TypeError: Cannot read property 'getFixedT' of undefined
    at Translate.componentWillMount (/Users/ank49/Documents/React Projects/Portfolio React i18n/node_modules/react-i18next/dist/commonjs/translate.js:84:46)

I initialized my i18n with the React and WebPack 2 example as the following :

import i18n from 'i18next'
import LanguageDetector from 'i18next-browser-languagedetector'

i18n.use(LanguageDetector)
    .init({
      loadPath:    'locales/{{lng}}/{{ns}}.json',
      preload:     ['en-US', 'fr-FR'],
      fallbackLng: 'fr-FR',
      // wait: true, // globally set to wait for loaded translations in translate hoc

      // have a common namespace used around the full app
      ns: ['common',
        'navbar',
        'footer',
        'header',
        'about',
        'experience',
        'skills',
        'p_app',
        'p_web',
        'cv',
        'social',
        'events',
        'contact',
        'support'],

      defaultNS: 'common',

      debug: true,

      // cache: {
      //   enabled: true
      // },

      interpolation: {
        escapeValue: false, // not needed for react!!
      },
      wait:          true,
    })

export default i18n

and my component I’m trying to translate is as follow :

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import withStyles from 'isomorphic-style-loader/lib/withStyles'
import Typist from 'react-typist'
import { translate } from 'react-i18next'
import { Parenthesis } from '../../components'

import style from './header.scss'

class Header extends Component {
  static propTypes = {
    t: PropTypes.func.isRequired,
  }

  render() {
    const { t } = this.props

    return (
      <div>

        <section className="header">
          <div className="header_content">
            <div className="header_content_inner">
              <h1 id="homeTextHead">{t('header.title')}</h1>
              <hr className="bg_dark"/>
              <br/>
              <Typist avgTypingDelay={90} className="typed_text">
                {t('header.name')}
                <br/>
                <Parenthesis>{t('header.pseudo')}</Parenthesis>
                <br/>
                <br/>
                {t('header.description')}
              </Typist>
            </div>
          </div>
        </section>

      </div>
    )
  }
}

export default withStyles(style)(translate(['header'], { wait: true })(Header))

I also tried with the decorator but I got the same issues…

@translate(['header'])
class Header extends Component {
...
}

export default withStyles(style)(Header)

Any help is welcome, thanks in advance guys !

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 36 (18 by maintainers)

Most upvoted comments

If anyone is having the error XMLHttpRequest is not defined using gatsby build, just install the package npm i -S xmlhttprequest and then in the top of gatsby-node.js file add:

// XMLHttpRequest polyfill
global.XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;

And now the build command works as expected, you can verify it by running gatsby serve.

I’ve read that, but it’s quite cumbersome. The closest I got is detailed below. I had to fuse all translation files into one per language otherwise it was beyond my webpack skills, but that defeats the point of loading just the relevant component’s translations by XHR. Besides, even with this I still have warnings during gatsby build. I think all these implementation details should be part of the package.

// src/utils/i18n.js, make sure to just import it from somewhere
import i18n from 'i18next'
import XHRBackend from 'i18next-xhr-backend'
import LanguageDetector from 'i18next-browser-languagedetector'
import { reactI18nextModule } from 'react-i18next'

const config = {
  fallbackLng: 'en',
  interpolation: {
    escapeValue: false, // code escaping in interpolated text is not needed with react
  },
  react: {
    wait: false,
  },
}

if(module.hot) {
  // config.debug = true
  config.resources = require('../locales')

  const translations = ['../locales/en.json', '../locales/fr.json']
  module.hot.accept(translations, () => reloadTranslations())
} else {
  i18n.use(XHRBackend)
}

i18n
  .use(LanguageDetector)
  .use(reactI18nextModule)
  .init(config)

function reloadTranslations() {
  const translations = require('../locales')
  Object.keys(translations).forEach(lang => {
    Object.keys(translations[lang]).forEach(namespace => {
      i18n.addResourceBundle(
        lang,
        namespace,
        translations[lang][namespace],
        true,
        true
      )
    })
  })

  i18n.emit('loaded')
}

export default i18n



// src/locales/index.js
const en = require('./en.json')
const fr = require('./fr.json')
export default { en, fr }

// src/locales/en.json
{
  "MyComponent": {
    "key1": "value1",
    ...
  }
}

Yes that was my next question, why not putting the translations into the source directly. But first I just need to get something working…

Like said…gatsby-plugin-i18n does the conversion of file extension file.en.js to a url /en/file.js not i18n. Personally naming that plugin i18n is misleading - better would be something like gatsby-plugin-i18n-routes or something like that.

From there you can use react-intl or react-i18next. You could even write a language detector plugin for i18n to read/set language from the url. Then fetch translations or use bundled translations.

Or even more awesome…write a real gatsby-plugin-i18next which takes the translations upfront and replaces translations during build time -> so the final /en/file.js is translated statically -> but might be contra productive if you got dynamic content (react components doing more than just static content) you doomed again (and honestly why one should use gatsby to only generate static content? Mixed content is where it shines in my opinion.