react-i18n useSuspense never ends if backend loading fails

1.5k Views Asked by At

In my react app, I am using i18next-http-backend to load translation data from backend response. Currently my app works fine in the below configuration:

config.js

import i18n from 'i18next';
import {initReactI18next} from 'react-i18next';
import HttpApi from 'i18next-http-backend';
import axios from "axios";

const backendOptions = {
    loadPath: 'http://localhost:3000/messages',

    request: async (options, url, payload, callback) => {
        try {
            const translation = await axios.get(url);
            callback(null,{
                status: 200,
                data: JSON.stringify(translation.data),
            });
        } catch (e) {
            callback(e);
        }
    },
};
const i18nextOptions = {
    debug:true,
    backend: backendOptions,
    fallbackLng: 'en',
    lng: 'en',
    load:"languageOnly",
    react: {
        useSuspense: true,
    },
    ns: ['translations'],
    defaultNS: 'translations'
}
i18n.use(initReactI18next)
    .use(HttpApi )
    .init(i18nextOptions);

i18n.languages = ['en', 'jp'];
i18n.on('failedLoading', function(lng, ns, msg) {
    console.log("backend error");
})
export default i18n;

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import './i18n/config';
import {store} from "./app/store";
import {Provider} from "react-redux";
import {ErrorBoundary} from "react-error-boundary";
import {Suspense} from "react";
import RuntimeErrorPage from "./features/error/runtime-error-page";
import Spinner from "./components/common/Spinner";

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <React.StrictMode>
        <ErrorBoundary FallbackComponent={RuntimeErrorPage}>
            <Suspense fallback={<Spinner/>}>
                <Provider store={store}>
                    <App/>
                </Provider>
            </Suspense>
        </ErrorBoundary>
    </React.StrictMode>
);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>

However, if there is any backend error, the app gets stuck in Suspense. If I disable suspense then the i18next initializes without any resource. How can I handle any error comes from request? I need a way to either invoke ErrorBoundary fallback component or redirect to any error page.

1

There are 1 best solutions below

0
On BEST ANSWER

i18next never throws an error...

Save those failed loadings somewhere else: https://codesandbox.io/s/react-i18next-http-example-forked-9ted7y?file=/src/i18n.js:188-295

and then create your own logic to show stuff: https://codesandbox.io/s/react-i18next-http-example-forked-9ted7y?file=/src/app.js:155-377

fyi: throwing inside an event listener is not a good idea

btw: why do you want to show an error when translations are not loaded? Why not showing a fallback text? The error is not intended for the end users anyway...