i18next::backendConnector: TypeError: 仅支持绝对 URL

时间:2021-05-14 20:52:02

标签: i18next react-i18next

我正在使用 i18next 来翻译我的 NextJs 应用程序。翻译在我的浏览器中加载得非常好,但我在控制台中仍然看到很少的错误。

i18next: hasLoadedNamespace: i18next was not initialized undefined
i18next::translator: key "resources.welcome_string.value" for languages "en-US" won't get resolved as namespace "myStrings" was not yet loaded This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!
i18next::translator: missingKey undefined myStrings resources.welcome_string.value resources.welcome_string.value
i18next::backendConnector: loading namespace myStrings for language en-US failed TypeError: Only absolute URLs are supported

这是我的 i18next 配置的样子 (src/i18n/i18n.ts):

import i18next from 'i18next';
import {initReactI18next} from 'react-i18next';
import httpApi from 'i18next-http-backend';

i18next
  .use(initReactI18next)
  .use(httpApi)
  .init({
    debug: process.env.NODE_ENV !== 'production',
    lng: 'en-US',
    ns: ['myStrings'],
    fallbackNS: 'myStrings',
    defaultNS: 'myStrings',
    fallbackLng:'en-US',
    preload: ['en-US', 'de-DE', 'es-ES'],
    interpolation: {
      prefix: "{{",
      suffix: "}}"
    },
    load: "currentOnly",
    supportedLngs: ['en-US', 'de-DE', 'es-ES'],
    backend: {
      loadPath: 'translations/{{ns}}-{{lng}}.json',
      crossDomain: true
    },
    detection: {
      order: ['cookie', 'htmlTag'],
    },
    react: {
      useSuspense: false
    },
  });

export default i18next;

这是我访问它的方式 (src/pages/localization.tsx):

import React from "react";
import Head from "next/head";
import { NextPage } from "next";
import "../i18n/i18n";
import {Trans, useTranslation} from 'react-i18next';

const Home: NextPage = (props: any) => {

  const { t, i18n } = useTranslation("myStrings");

  return (
    <div>
      <Head>
        <title>Home</title>
      </Head>
      <div>
          <kat-flag size="small" country="us" onClick={() => i18n.changeLanguage("en-US")}> US </kat-flag>
          <kat-flag size="small" country="de" onClick={() => i18n.changeLanguage("de-DE")}> DE </kat-flag>
          <kat-flag size="small" country="es" onClick={() => i18n.changeLanguage("es-ES")}> ES </kat-flag>
          <hr/>
          <hr/>
          <div> {t("resources.welcome_string.value")} </div>
      </div>
    </div>
  );
};

export default Home;

我可能理解在 localization.tsx 中初始化 i18next 之前加载我的代码 i18n.ts 的错误。

我的问题是:

  1. 我该如何解决这个问题?我怎样才能让 i18next.init 先加载
  2. 我目前正在使用 i18next-http-backend,因此我的翻译字符串必须位于 public 文件夹中。有什么方法可以将我的翻译保存在非公共文件夹中(与 srcpublic 平行)并从那里加载。

2 个答案:

答案 0 :(得分:0)

  1. 这在一定程度上取决于您的架构 - i18next.init() 返回一个 promise,您可以简单地将其导出并在代码中的某处等待它。或者,您可以通过 i18next.on('initialized',()=>...)

    建立侦听器
  2. 翻译必须在公共文件夹中,因为 this folder gets bundled as-is during your build process(因此文件不会被重命名)。理论上,您可以使用不同的文件夹,但您只需要确保之后将其包含在您的包中即可。

答案 1 :(得分:0)

Next.js 也在服务器端执行,这意味着您的 loadPath 需要是绝对的,例如:https://my-domain.com/translations/{{ns}}-{{lng}}.json