1
votes

I'm trying to use react-i18next on the client using the i18next-fetch-backend, and even though I can get to the JSON translation files via a browser, something is screwy with how they're being handled during the init routine.

For the record, I'm using create-react-app as the basis of my front-end React application, if that makes a difference, and so far all of my testing is in localhost (with the React app on localhost:3000, and the "server" on localhost:8000).

Here's my init file:

import i18n from 'i18next';

import LanguageDetector from 'i18next-browser-languagedetector';
import Cache from 'i18next-localstorage-cache';
import Fetch from 'i18next-fetch-backend';

i18n
  .use(LanguageDetector)
  .use(Cache)
  .use(Fetch)
  .init({
    fallbackLng: 'en', 
    ns: ['common','app'],
    defaultNS: 'common',
    preload: ['en'], 
    wait: true,
    backend: {
      loadPath: 'http://localhost:8000/static/locales/{{lng}}/{{ns}}.json',
      addPath: 'http://localhost:8000/static/locales/{{lng}}/{{ns}}',
      parse: function (data) { console.log("DATA", data) },
      init: {
        mode: 'no-cors',
        credentials: 'include',
        cache: 'default'
      }
    },

    cache: {
      enabled: true,
      prefix: 'i18next_translations_',
      expirationTime: 24*60*60*1000 //one day
    },

    debug: true,

    detection: {
      order: ['localStorage', 'cookie'], 
      lookupCookie: 'i18nextLng',
      lookupLocalStorage: 'i18nextLng',
      caches: ["localStorage"] 
      //cookieMinutes: 10 // if we want the cookie to expire
    },

  });

export default i18n;

...and then the Component that wraps my app looks like this:

import React, { Component } from 'react';

import { I18nextProvider } from 'react-i18next'
import i18n from './i18n' // the init code from above

export default class Localize extends Component {
  render () {
    return (
      <I18nextProvider i18n={i18n}>
        {this.props.children}
      </I18nextProvider>
    )
  }
}

...and finally, the Component where the translation should happen:

class TestTranslate extends Component {

  render () {
    const { t } = this.props;
    return (
      <div>
          {t('key1')}
          {t('key3')}
      </div>
    )
  }
}

export default translate()(LearnHome)

If I look at the Chrome debugger when I load the page, I see the following: Chrome console

Two FETCH commands are executed: one for common.json and one for app.json. To my eye, it sure looks like both FETCH commands execute properly, but then no data at all is making it to the parse() function in the backend init config data.

And in fact, if I pop over to the Chrome network tab, the browser sure seems to think that the data was properly returned to the browser from the server:

Chrome network tab

So I'm baffled as to what's going on. I've pored through the i18next docs and several examples, but have so far come up empty. Any help is appreciated.

Thanks!

1
The question itself is the best resource I've found for setting up react-i18next.np8

1 Answers

1
votes

Okay, I figured this out. It's got nothing to do with i18next. We are running a Django built-in dev web server inside a Vagrant instance for local development. By default, Django's web server doesn't put headers on static files as they are returned to the client. My local client environment (localhost:3000) was in essence making a CORS request to my local Django environment (localhost:8000), so we had to reconfigure our dev Django server to return CORS headers on static file requests.