简体   繁体   中英

React i18next fails to load translation after in build

I don't know why react i18next display loading namespace fails on the debug console. I tried many suggestions without success. I'm using the react build folder inside Django project.

It works fine on localhost:3000 only which is crazy but once i try to use the build folder I get the above error on the debug console

i18n.js :

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import Backend from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';

// don't want to use this?
// have a look at the Quick start guide
// for passing in lng and translations on init

const Languages = ['ar', 'en', 'fr']

i18n
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next) // passes i18n down to react-i18next
  .init({
    lng: 'en',
    react: {
      useSuspense: true,
    },
    // the translations
    // (tip move them in a JSON file and import them,
    // or even better, manage them via a UI: https://react.i18next.com/guides/multiple-translation-files#manage-your-translations-with-a-management-gui)
    supported: ["en", "fr", "ar"],
    fallbackLng: "en",
    detection: {
      order: ['path', 'cookie', 'htmlTag', 'localStorage', 'subdomain'],
      caches: ['cookie'],
    },
    debug: true,
    whitelist: Languages,
    interpolation: {
      escapeValue: false, // not needed for react as it escapes by default
    },
    nsSeperator: false,
    keySeperator: false,
    backend: {
      loadPath: '/locales/{{lng}}/{{ns}}.json',
    },
  });

export default i18n;

index.js :

import React, {Suspense} from 'react';
import ReactDOM from 'react-dom';
import i18n from "i18next";
import { I18nextProvider } from "react-i18next";
import App from './App';
import 'bootstrap/dist/css/bootstrap.min.css';
import './index.css';
import './i18n';

  ReactDOM.render(
    <React.StrictMode>
      <Suspense fallback={(<div className='index__loading'><h2>Loading...</h2></div>)}>
        <I18nextProvider i18n={i18n}>
          <App />
        </I18nextProvider>
      </Suspense>,
    </React.StrictMode>,
    document.getElementById('root')
  );

loginheader.js :

import React, { Fragment, useEffect, useState } from 'react';
import './LoginHeader.css'
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import { logout } from '../actions/auth';
import SortIcon from '@mui/icons-material/Sort';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import Alert from './Alert';
// import Drower from './Drower';
import Logo from '../assets/images/logo.png';
import { useTranslation } from "react-i18next";
import { FormControl, Select, MenuItem } from '@mui/material';
// import LanguageIcon from '@mui/icons-material/Language';
import i18next from 'i18next';
import cookies from 'js-cookie';

const languages = [
  {
    code: 'fr',
    name: 'Français',
    country_code: 'fr'
  },
  {
    code: 'en',
    name : 'English',
    country_code: 'en'
  },
  {
    code: 'ar',
    name: 'العربية',
    country_code: 'ly',
    dir: 'rtl'
  }
]

function LoginHeader({ logout, isAuthenticated }) {

  const currentLanguageCode = cookies.get('i18next') || 'en';
  const currentLanguage = languages.find(l => l.code === currentLanguageCode);
  useEffect (() => {
    document.body.dir = currentLanguage.dir || 'ltr'
    // document.title = t('app_title')
  },[currentLanguage]);

  const { t } = useTranslation()
  const [value, setValue] = useState('English')
  const handleChange = (event) => {
    setValue(event.target.value)
  }
  
  const guestLinks = () => (
    <Fragment>
      <div className='loginHeader__right'>
        <div className='middle__header__bx'>
    
          <div className='loginHeader__main__btns'>
            <Link className='loginHeader__loginButton' to='/login'><button>{t('header_login')}</button></Link>
            <Link className='loginHeader__signupButton' to='/signup'><button>{t('header_signup')}</button></Link>
          </div> 
        
          <div className='loginHeader__services__dropdown'>
          <button className='dropdown__btn dropdown__services'>{t('header.services')}<ExpandMoreIcon className='services__expand'/></button>
          <div className='dropdown__content dropdown__services__content'>
            <Link className='loginHeader__menuItem' to='/visa-assist'>{t('services_visaAssist')}</Link>
            <Link className='loginHeader__menuItem' to='/admission'>{t('services_addmissionOffers')}</Link>
            <Link className='loginHeader__menuItem' to='/application-form'>{t('services_forms')}</Link>
            <Link className='loginHeader__menuItem' to='/premuim-support'>{t('services_premium')}</Link>
          </div>
        </div>
        {/* start of lang box */}
        <div className='loginHeader__lang'>
          <div className='loginHeader__lang__bx'>
            <div className='loginHeader__lang__container'>
              <Select
                className='loginHeader__select'
                labelId='select-demo'
                id='language-select'
                value={value}
                onChange={handleChange}
                disableUnderline
                variant='standard'
              >
                {languages.map(({code, name, country_code}) => 
                  <MenuItem
                    value={name} 
                    key={country_code}
                  >
                    <button 
                      onClick={() => i18next.changeLanguage(code)}
                      className='loginHeader__lang__btn'
                    >
                      {name}
                    </button>
                  </MenuItem>
                )}
              </Select>
            </div>
          </div>
        </div>
        {/* end of lang box */}
        <div className='loginHeader__services__dropdown sortIcon__bx'>
          <SortIcon className='dropdown__btn loginHeader__sortIcon'/>
          <div className='dropdown__content sortIcon__dropdown'>
            <Link className='loginHeader__menuItem' to='/premuim-support'>{t('header_dropdown_prem')}</Link>
            <Link className='loginHeader__menuItem' to='/visa-assist'>{t('header_dropdown_visaAssist')}</Link>
            <Link className='loginHeader__menuItem' to='/admission'>{t('header_dropdown_admission')}</Link>
            <Link className='loginHeader__menuItem' to='/request-service'>{t('header_dropdown_requestService')}</Link>
            <Link className='loginHeader__menuItem' to='/contact'>{t('header_dropdown_contact')}</Link>
            <Link className='loginHeader__menuItem' to='/signup'>{t('header_signup')}</Link>
            <Link className='loginHeader__menuItem' to='/login'>{t('header_login')}</Link>
            <Link className='loginHeader__menuItem' to='/guid'>{t('header_dropdown_guide')}</Link>
          </div>
        </div>
        
       </div>
      </div>
    </Fragment>
  );

  const authLinks = () => (
    <Fragment>
      <div className='loginHeader__right'>
      {/* <button onClick={logout} className='loginHeader__logout__btn'>{t('header_logout')}</button> */}
        {/* start of lang box */}
        <div className='loginHeader__logged__lang'>
          <div className='loginHeader__lang__bx'>
            <FormControl>
              <Select
                className='loginHeader__select'
                labelId='select-demo'
                id='language-select'
                value={value}
                onChange={handleChange}
                disableUnderline
                variant='standard'
              >
                {languages.map(({code, name, country_code}) => 
                  <MenuItem
                    value={name} 
                    key={country_code}
                  >
                    <button 
                      onClick={() => i18next.changeLanguage(code)}
                      className='loginHeader__lang__btn'
                      disabled={code === currentLanguageCode}
                    >
                      {name}
                    </button>
                  </MenuItem>
                )}
              </Select>
            </FormControl>
          </div>
        </div>
        {/* end of lang box */}
      <div className='loginHeader__services__dropdown loggedin__icon__bx'>
          <button className='dropdown__btn'><SortIcon className='loginHeader__sortIcon logedin__sortIcon'/></button>
          <div className='dropdown__content logged__sortIcon__dropdown'>
            <Link className='loginHeader__menuItem' to='/premuim-support'>{t('header_dropdown_prem')}</Link>
            <Link className='loginHeader__menuItem' to='/admission'>{t('header_dropdown_admission')}</Link>
            <Link className='loginHeader__menuItem' to='/visa-assist'>{t('header_dropdown_visaAssist')}</Link>
            <Link className='loginHeader__menuItem' to='/request-service'>{t('header_dropdown_requestService')}</Link>
            <Link className='loginHeader__menuItem' to='/contact'>{t('header_dropdown_contact')}</Link>
            <Link className='loginHeader__menuItem' to='/guid'>{t('header_dropdown_guide')}</Link>
            <button onClick={logout} className='logout__btn'>{t('header_logout')}</button>
          </div>
      </div>
      </div>
    </Fragment>
  );

  return (
    <div className='loginHeader'>
      <div className='loginHeader__left'>
        <Link to='/'><img className='logo' src={Logo} alt='logo'/></Link>  
      </div>
      {isAuthenticated ? authLinks() : guestLinks()}
      <Alert/>
    </div>
  )
};

const mapStateToProps = state => ({
  isAuthenticated: state.auth.isAuthenticated
});

export default connect(mapStateToProps, { logout }) (LoginHeader);

debug console:

DevTools failed to load source map: Could not load content for chrome-extension://gighmmpiobklfepjocnamgkkbiglidom/browser-polyfill.js.map: System error: net::ERR_FILE_NOT_FOUND

i18next.js:27 i18next::backendConnector: loading namespace translation for language en failed failed parsing /locales/en/translation.json to json

locales/en/translation.json ;

{
    "app_title": "welcome page",

    "header.services": "Services",
    "header_login": "Login",
    "header_signup": "Sign up",
    
    "services_visaAssist": "Visa Assist",
    "services_addmissionOffers": "Admission Offers",
    "services_forms": "Filling Visa Forms",
    "services_premium": "Premium Support",

    "header_dropdown_prem": "Request Premium",
    "header_dropdown_admission": "Request Admission",
    "header_dropdown_visaAssist": "Request Visa Assist",
    "header_dropdown_requestService": "Request Service",
    "header_dropdown_contact": "Contact us",
    "header_dropdown_guide": "Guide",

    "header_logout": "Logout",

    "login_title": "Login",
    "login_lead": "Login into your Account",
    "login_text1": "Do not have an account? ",
    "login_text2": "Forgot Password? ",
    "login_register": "Register",
    "login_reset": "Reset Password",

    "signin_title": "Sign Up",
    "signin_lead": "Create your Account",
    "signin_text1": "Already have an account? ",
    "signin_text2": "* Password must contain : digits, uppercase, lowercase characters & special characters.",
    "signin_text3": "Must contain at least one number, one uppercase, lowercase letter, special characters and at least 8 or more characters",
    "signin_toLogin": "Login",

    "reset_pw": "Request Password Reset :",
    "reset_btn": "Reset Password",

    "activate_title": "Verify your Account :",
    "activate_btn": "Verify !",

    "contact_title": "Contact Us",
    "contact_subjct": "Subject *",

    "request_title": "Request Service",
    "request_text": "Request",


    "welcome_title": "Welcome to ",
    "welcome_titleMid": "Diploma",
    "welcome_titleEnd": "n",

    "serviceCard_title": "Services",

    "admission_card": "Admission Offers",
    "admission_subtitle": "Language Offer Services :",
    "admission_li1": " Get offers without charges",
    "admission_li2": " Hit Target & Win some money Back",
    "admission_li3": " Proactive Checks & tips for exams",
    "admission_li4": " Academic offers (Soon)",

    "card_learnMore": "Learn More",

    "assist_card": "Visa Assist",
    "assist_subtitle": "Visa Assist Services :",
    "assist_li1": " Filling Visa Application-Form",
    "assist_li2": " Book Biometrics Apointments",
    "assist_li3": " Review Required Documents",
    "assist_li4": " Reccomendations",

    "premium_card": "Full Support",
    "premium_subtitle": "Premium Support Services :",
    "premium_li1": " Priority Aplicant",
    "premium_li2": " Proactive follow-up",
    "premium_li3": " Admission Sercices (included)",
    "premium_li4": " Visa Assist Services (included)",

    "guide_card": "Guide",
    "guide_desc": "Studying abroad may seem complicated and that's why we are here to make the processes simple.",

    "about_title": "Diploman at your service",
    "about_desc": "We are an official partner to language and academic institutes. We provide admission offers & travel-visa support for (Students, Businessmen and Medical cases ). No charges on Admission offers (free) + financial award at the end of study ( for + 5 months) ",
    "about_li1": "Recommendations and Proactive follow-up",
    "about_li2": "Premium : Special service from A2Z",
    "about_li3": "Filling application forms",
    "about_li4": "Provide admission offers",
    "about_li5": "Visa support",

    "schools_title": "Language Centers",

    "footer_services": "Services",
    "footer_admission": "Admission Offers",
    "footer_visaAssist": "Visa Assist",
    "footer_guide": "Guide",

    "footer_links": "Links",
    "footer_about": "About",
    "footer_contact": "Contact us",
    "footer_partners": "Partners",

    "footer_diploman": "Diploman",
    "footer_paragraph": "Our goal is to make prosperity for all by bridging the gap between learners and language centers (Soon Aacademic institutes), and help not only get admission with no extra fees but win some money back.",

    "admissionForm_request": "Request Admission Offer",
    "admissionForm_course": "24 weeks *",
    "admissionForm_startDate": "Course Start Date",
    "admissionForm_CourseLength": "Course Length",
    "admissionForm_school": "School Name",
    "admissionForm_select": "Select School",
    "admissionForm_otherSchool": "Other",

    "requestAdmission_header": "Start your journey by requesting an Admission offer",
    "admissionProcess_header": "Prosparity for All ",
    "admissionProcess_ul": "Benefits of our Admission services :",
    "admissionProcess_li1": "Admission offers without charges.",
    "admissionProcess_li2": "Study +5 Months and win a financial award.",
    "admissionProcess_li3": "Proactive checks and tips to help you reach your target.",
    "admissionProcess_subTitle": "All Payments are direct to school !",
    "admissionProcess_note": "* note : Some school require deposit fees before providing admission offer and full payment 2 weeks before starting date",

    "va_title": "Start by requesting Visa-Assist package",
    "requestVA_title": "Request Visa-Assist",

    "vaProcess_subtitle": "Visa-Assist service price varies acording to applicants and destination.",
    "vaProcess_note": "* note : there's discounts for groups and students who obtained admissioin through us upon request.",
    "vaProcess_li1": "The process varies according to applicant. Here are some benefits :",
    "vaProcess_li2": "Review required documents.",
    "vaProcess_li3": "Filling application-forms.",
    "vaProcess_li4": "Booking biometric appointment.",
    "vaProcess_li5": "Recomendations.",

    "prem_header": "Go Premium",
    "prem_subtitle": "Go premuim and we'll do it all :",
    "prem_li1": "Provide addmission offer.",
    "prem_li2": "Filling application-forms.",
    "prem_li3": "Booking biometric appointment.",
    "prem_li4": "Proactive follow-up.",
    "prem_li5": "Recomendations.",
    "prem_price": "Premuim service price is 69€.",
    "prem_note": "* note : To get admission offer some school require deposit fees before providing admission offer and full payment 2 weeks before starting date.",
    "premSupport_header": "Start your journey by requesting premuim-service",
    "premform_title": "Request Premuim-Support",

    "guideProcess_title": "Simple Guide",
    "guideProcess_text": "If you need a visa to visit a country, there are two ways to get the job done : to plan your trip by yourself :",
    "guideProcess_subText": "service and our team will guide you. We will fill application-form and book appointment on your behalf. Supported Destinations : UK, USA, Malta, Malaysia and Canada, (Other countries upon request).",
    "guideProcess_li1": "Choose your dstination.",
    "guideProcess_li2": "Check visa requirments.",
    "guideProcess_li3": "Translate documents.",
    "guideProcess_li4": "Fill application-form.",
    "guideProcess_li5": "Book appointment.",
    "guideProcess_li6": "Apply for visa.",
    "guideProcess_or": "Or",
    "guideProcess_request": "Request",

    "requiredDoc_title": "Common Required Documents for Travel Visa :",
    "requiredDoc_li1": "Study",
    "requiredDoc_li2": "* Admission Offer",
    "requiredDoc_li3": "* Accomodation details",
    "requiredDoc_li4": "* Birth certificate",
    "requiredDoc_li5": "* Bank Statement",
    "requiredDoc_li6": "Employed :",
    "requiredDoc_li7": " + Reference letter",
    "requiredDoc_li8": " + Leave letter",
    "requiredDoc_li9": "If sponsored :",
    "requiredDoc_li10": "+ Sponsor lettery",
    "requiredDoc_li11": " + bank statement (not government sponsors)",
    "requiredDoc_li12": "Fresh Graduate :",
    "requiredDoc_li13": " + Graduation Certificate",
    "requiredDoc_li14": "Business",
    "requiredDoc_li15": "* Invitation letter",
    "requiredDoc_li16": "* Accomodation details if available",
    "requiredDoc_li17": "* Reference letter from employer",
    "requiredDoc_li18": "* Birth certificate",
    "requiredDoc_li19": "Other",
    "requiredDoc_li20": "* Accomodation details",
    "requiredDoc_li21": "* Invitation letter if invited",
    "requiredDoc_li22": "* Bank statement",
    "requiredDoc_li23": "* Birth certificate",
    "requiredDoc_li24": "Medical Treatment :",
    "requiredDoc_li25": " + Medical invitation letter",
    "requiredDoc_li26": " + Medical reports",
    "requiredDoc_li27": " + Financial or Sponsor details",
    "requiredDoc_note": "note : These documents are required at Visa-Section on the date of your appointment",


    "Form_name": "Name *",
    "Form_email": "Email *",
    "Form_phone": "Phone *",
    "Form_destinstion": "Destination (Country) *",
    "Form_message": "Message (optional)",
    "Form_send": "Send",
    "Form_pw": "Password *",
    "Form_rePw": "Confirm Password *"

}

Results on debug console network. before build all ok on localhost:3000 ;

Request URL: http://localhost:3000/locales/en/translation.json
Request Method: GET
Status Code: 304 OK
Remote Address: 127.0.0.1:3000
Referrer Policy: strict-origin-when-cross-origin
Accept-Ranges: bytes
Access-Control-Allow-Headers: *
Access-Control-Allow-Methods: *
Access-Control-Allow-Origin: *
Cache-Control: public, max-age=0
Connection: keep-alive
Date: Sat, 02 Jul 2022 13:48:15 GMT
ETag: W/"22cc-181ba138961"
Keep-Alive: timeout=5
Last-Modified: Fri, 01 Jul 2022 14:04:11 GMT
X-Powered-By: Express
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Cookie: i18next=en
Host: localhost:3000
If-Modified-Since: Fri, 01 Jul 2022 14:04:11 GMT
If-None-Match: W/"22cc-181ba138961"
Referer: http://localhost:3000/
sec-ch-ua: ".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36

After build (not working) on localhost:8000 ;

Request URL: http://127.0.0.1:8000/locales/en/translation.json
Request Method: GET
Status Code: 200 OK
Remote Address: 127.0.0.1:8000
Referrer Policy: same-origin
Content-Length: 948
Content-Type: text/html; charset=utf-8
Cross-Origin-Opener-Policy: same-origin
Date: Sat, 02 Jul 2022 13:54:00 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.10.2
Vary: Origin
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Cookie: csrftoken=KKBUsud0hxf0n2XkfSuQw9Hx3RLkHnSTyJHzGL8xyg502fPxxcDab3113rLJxQyu; i18next=en
Host: 127.0.0.1:8000
Referer: http://127.0.0.1:8000/
sec-ch-ua: ".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36

I suspect your locales/en/translation.json file is not a valid json.

https://jsonlint.com

validate it, or paste it here so we can check.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM