i18n从s3bucket加载翻译

时间:2020-07-10 13:53:25

标签: reactjs amazon-s3 i18next i18next-http-backend

我正在我的React App中使用i18n模块,该模块作为S3上的应用程序(我称为实时应用程序)托管,并且cloudfront位于它。

我想将s3网址存储在配置文件中,以避免在应用中对其进行硬编码,以便在开发时可以处理本地存储在public/locales文件夹中的翻译文件。

最初,我设置了后端选项,因此它将始终尝试在locales路径中查找文件。尽管S3存储桶中存在locales文件夹,但此操作在本地有效,但停止在S3上工作。我还注意到,该应用没有发送任何请求来检索翻译文件。

backend: {
    loadPath: 'locales'
  }

然后,我决定将翻译文件上传到另一个S3存储桶,并将其托管在该存储桶中,以查看是否可以解决问题。 我更改了配置以对s3存储桶路径进行硬编码。这在本地和实时应用程序上均有效。但这意味着我无法使用配置文件来确定loadPath选项。

 backend: {
    loadPath: '<myhardcoded-s3-bucket-url>/{{lng}}/translation.json',
    crossDomain: true
  }

然后我以为可以按原样构造网址:

/*global AWS_CONFIG */
/*eslint no-undef: "error"*/
...
...
...
backend: {
    loadPath: `${AWS_CONFIG.aws_app_translations_path}/{{lng}}/translation.json`,
    crossDomain: true
  }

奇怪的是,当AWS_CONFIG.aws_app_translations_path既是http://localhost:3000/locales又是<myhardcoded-s3-bucket-url>时,这种方法在本地仍然有效。 但是,一旦我将其发布,它再次失败。例如,这次向https://<my-apps-base-path>/undefined/en-GB/translation.json发出请求。因此,它试图使用应用程序路径并附加我在loadPath中定义的内容。

然后,我看到可以将loadPath作为构造URL的函数。这对于实时应用程序也不起作用,但在本地也适用。

backend: {
    loadPath: function (lng) {
      return `${AWS_CONFIG.aws_app_translations_path}/${lng}/translation.json`
    },
    crossDomain: true
  }

这是我的整个i18n文件

/*global AWS_CONFIG */
/*eslint no-undef: "error"*/
import i18n from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import Backend from "i18next-http-backend";
import { initReactI18next } from "react-i18next";


const options = {
  order: ['navigator', 'localStorage'],
  caches: ['localStorage'],
  fallbackLng: "en-GB",
  debug: true,
  interpolation: {
    escapeValue: false // not needed for react as it escapes by default
  },
  backend: {
    loadPath: function (lng) {
      return `${AWS_CONFIG.aws_app_translations_path}/${lng}/translation.json`
    },
    crossDomain: true
  }
}

i18n
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init(options);

export default i18n;

什么可以解释这种奇怪的行为?我在这里缺少配置吗?

2 个答案:

答案 0 :(得分:0)

根据您在评论中的回复,您似乎缺少翻译部分,并且它在网址中预先添加了undefined作为名称空间。

尝试一下:

// i18n

const options = {
  order: ['navigator', 'localStorage'],
  caches: ['localStorage'],
  fallbackLng: "en-GB",
  debug: true,
  interpolation: {
    escapeValue: false // not needed for react as it escapes by default
  },
  backend: {
    loadPath: function () {
      return `${AWS_CONFIG.aws_app_translations_path}/{{lng}}/{{ns}}.json`
    },
    crossDomain: true
  }
}

基于loadPath配置文档:

从中加载资源的路径或函数 返回路径: function(lngs,namespaces){返回customPath; }

如果提供的路径类似于静态路径,则返回的路径将内插lng,ns

答案 1 :(得分:0)

一旦我更改了导入配置文件的方式,它就会起作用。我想实时存在加载问题,但是我的i18n文件已从

更改
/*global AWS_CONFIG */
/*eslint no-undef: "error"*/
import i18n from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import Backend from "i18next-http-backend";
import { initReactI18next } from "react-i18next";


const options = {
  order: ['navigator', 'localStorage'],
  caches: ['localStorage'],
  fallbackLng: "en-GB",
  debug: true,
  interpolation: {
    escapeValue: false // not needed for react as it escapes by default
  },
  backend: {
    loadPath: function (lng) {
      return `${AWS_CONFIG.aws_app_translations_path}/${lng}/translation.json`
    },
    crossDomain: true
  }
}

i18n
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init(options);

export default i18n;

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

const {aws_app_translations_path} = config;


const options = {
  order: ['navigator', 'localStorage'],
  caches: ['localStorage'],
  fallbackLng: "en-GB",
  debug: true,
  defaultNS: 'translation',
  load: 'currentOnly',
  interpolation: {
    escapeValue: false // not needed for react as it escapes by default
  },
  backend: {
    loadPath: (lng, ns) => {
      return `${aws_app_translations_path}/${lng}/${ns}.json`;
    },
    crossDomain: true
  }
}

i18n
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init(options);

export default i18n;

解决了。最初AWS_CONFIG 会以未定义的形式返回,尽管适用于整个应用程序的其余部分。更改配置文件以使其位于项目的根目录中,并导入该文件即可解决该问题。