i18n загрузить переводы из s3bucket
Я использую i18n
модуль в моем приложении для реагирования, которое размещено как приложение (которое я буду называть живым приложением) на S3
и имеет cloudfront
сидя перед ним.
Я хочу сохранить URL-адрес s3 в файле конфигурации, чтобы избежать его жесткого кодирования в моем приложении, чтобы я мог работать с файлами перевода, хранящимися локально в public/locales
папка, когда я разрабатываю.
Изначально у меня были настройки бэкэнда, чтобы он всегда пытался искать файлы в locales
путь. И это работало локально, но перестало работать на S3, хотя папка locales присутствовала в корзине S3. Я также заметил, что из приложения не отправляется запрос на получение файлов перевода.
backend: {
loadPath: 'locales'
}
Затем я решил загрузить файлы перевода в другую корзину S3 и разместить их там, чтобы посмотреть, решит ли это проблему. Я изменил свою конфигурацию, чтобы жестко указать путь к ведру s3. Это работало как локально, так и в реальном приложении. Но это означает, что я не могу использовать свой файл конфигурации для определения опции loadPath.
backend: {
loadPath: '<myhardcoded-s3-bucket-url>/{{lng}}/translation.json',
crossDomain: true
}
Затем я подумал, что могу построить URL-адрес так:
/*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 ответа
Судя по вашим ответам в комментариях, похоже, что вам не хватает части перевода, и она перед добавлением undefined
как пространство имен в URL-адресе.
Попробуй это:
// 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) { return customPath; }
Возвращенный путь будет интерполировать lng, ns, если он предоставлен как статический путь
Как только я изменил способ импорта файла конфигурации, все заработало. Я предполагаю, что есть проблема с загрузкой вживую, но изменив файл 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
возвращался как undefined, несмотря на то, что работал для остальной части всего приложения. Изменение файла конфигурации для размещения в корневом каталоге проекта и способ его импорта решили проблему.