I have successfully installed the vue-fb-customer-chat plugin in my NuxtJS website and the chat is working fine.
It is a multilangual website and I need to be able to load the chat in the right language (current locale from the nuxt-i18n module). It is okay if the chat does not change its language after switching the language from within the website, but I'd like to at least have the correct language when the page loads.
Here's the content of plugins/vue-fb-customer-chat.js file:
import Vue from 'vue'
import VueFbCustomerChat from 'vue-fb-customer-chat'
Vue.use(VueFbCustomerChat, {
page_id: null, // change 'null' to your Facebook Page ID,
theme_color: '#845e5c', // theme color in HEX
locale: 'fr_FR', // default 'en_US'
})
None of the following works:
context.app.i18n.locale
this.$i18n.locale
$i18n.locale
What would the approach be to solve this issue?
Thank your for your help in advance.
My colleague anwsered my question.
import Vue from 'vue'
import VueFbCustomerChat from 'vue-fb-customer-chat'
export default function (context) {
const locale = context.app.i18n.locale;
const iso = context.app.i18n.locales.find(l => l.code === locale).iso;
Vue.use(VueFbCustomerChat, {
page_id: null, // change 'null' to your Facebook Page ID,
theme_color: '#845e5c', // theme color in HEX
locale: iso.replace('-', '_'), // default 'en_US'
})
}
Related
I am trying to translate a React web app with the click of a button using i18n with the translations coming from .js files, not .json.
Here's the setup:
I have the i18n file:
const resources = {
en: enTranslation,
de: deTranslation,
};
i18n
.use(Backend)
.use(initReactI18next)
.init({
fallbackLng: "de",
debug: true,
resources,
interpolation: {
escapeValue: false,
},
});
export default i18n;
The imported "enTranslation" and "deTranslation" files are .js files with the respective language options. I import image files into those to use for some variables so a JSON file wouldn't work.
Excerpt example:
import pen from "../images/pen.jpg";
import table from "../images/table.jpg";
export const enTranslation = {
translation: {
imagePen: pen,
imageTable: table
}
}
The setup of the web app is as follows:
I have a "home.js" file where I define the structure of the page, like this:
const Home = () => {
const { t, i18n } = useTranslation();
return (
<>
<HeroSection {...**heroSectionContent**} />
<InfoSection {...infoSectionContents[0]} />
<Services {...cardSectionContent} />
<InfoSection {...infoSectionContents[1]} />
);
};
export default Home;
// page content objects
const **heroSectionContent** = {
header: i18next.t("header"),
description: i18next.t("intro"),
};
The contents for the different sections are all stored in constants below the React components, I included the hereSectionContent as an example.
This all works fine and if I change the fallback language in the i18n file, it shows the correct text. However, I would like to include a language switch for the user to be able to change the language, preferably without reloading the website. One section is made up of a multi-page questionnaire so reloading would throw the user back to page 1 and lose all the entered data.
Here's the LanguageSwitcher function I'm using:
function LanguageSwitcher() {
const { i18n } = useTranslation();
return (
<div className="select">
<select
value={i18n.language}
onChange={(e) => i18n.changeLanguage(e.target.value)}
>
<option value="de">Deutsch</option>
<option value="en">English</option>
</select>
</div>
);
}
export default LanguageSwitcher;
I noticed that if I refer to any of the text of the translation files directly out of the React return component, it works. Example:
Instead of writing
<HeroP>{heroSectionContent.description}</HeroP>
Changing it to
<HeroP>{t("intro")}</HeroP>
Works!
Is there any way to get this language switcher to work without having to write the i18n references into the return section?
Sorry if something is rather unclear or poorly worded, still pretty new to React.
Many thanks in advance!
I am using i18next in a Gatsby and React app to handle internationalization. The website is in french and english and works well. The only issue is that when I set the language to french and refresh, I notice a short delay where language is not yet loaded, so it gives me english version (which is the language I set for fallback), and quickly returns to french.
My i18next config file:
import i18n from "i18next";
import fr from "./i18n/fr.json";
import en from "./i18n/en.json";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
const resources = {
fr: {
translation: fr
},
en: {
translation: en
}
};
i18n
.use(LanguageDetector)
.use(initReactI18next)
.init({
resources,
fallbackLng: "en",
returnObjects: true,
interpolation: {
escapeValue: false
}
});
export default i18n;
Do you have any idea how to remove this delay and load the page directly to the chosen language ?
I had this problem. Firstly, I changed fallbackLng like this
import Cookies from 'js-cookie';
const cookieLanguage = Cookies.get('i18next');
fallbackLng: cookieLanguage ? cookieLanguage : 'en'
then I wrote in my onClick function
const [langChanged, setLangChanged] = useState(null);
const language = Cookies.get('i18next');
const changeLanguageHandler = (e) => {
const newLang = e.target.innerText.toLowerCase();
if (language !== newLang) {
window.location.reload(true);
broadcastChannel.postMessage("language changed");
setLangChanged(newLang);
}
}
And I used langChanged state like dependency in useEffect
useEffect(() => {
if (langChanged) {
i18next.changeLanguage(langChanged)
}
}, [langChanged])
So it returns same delay to every language
I suppose the fallback language is server-side rendered, and other languages are not.
If you click "view page source" in the browser you can see the original HTML code. I suppose you will see the english text, even if french is displayed on the page.
(Note that "inspect" will display french, because this includes all dynamic changes to the DOM, while "view page source" will display the original server response.)
So you need to render non-default languages on the server as well:
In case you store the language in a cookie, then you can query the cookie at the server-side, and send the correct text accordingly.
Alternatively you can use the URL to inform the server about the desired language (e.g. `/fr/mypage).
I don't use i18next, but you probably need to set the "initial store" to the desired language on the server-side, instead of set the fallback language as "initial store" and set the desired langage afterwards.
I read that you can set initialI18nStore and initialLanguage for the I18nextProvider
See also react.i18next Server Side Rendering
I have the vueI18n package installed for language localization in the app and the locale messages object is fetched through an api call. I have config file where the default language is specified and based on which the locale will be loaded before the app.vue is created. ie; I'm loading the locale in beforeCreate lifecycle method. But still the text are not loaded properly.
Initially the message object is null because based on the user config we are fetching the language and loading the messages. I am assuming the initial empty object is causing the issue.
Could someone suggest a way we can delay the page load until we confirm the message object is loaded successfully.
vueI18 config file
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import userConfig from './userConfig'
import apiService from '#/service/apiService.js'
let selectedLanguage = ''
Vue.use(VueI18n)
const loadLocaleMessages = async (lang) => {
const messages = await apiService.getLocale(lang)
return messages
}
export const i18n = new VueI18n({
locale: selectedLanguage,
fallbackLocale: userConfig.defaultLocalizationKey,
formatFallbackMessages: true,
messages: {}
})
export const loadLanguage = async lang => {
const messages = await loadLocaleMessages(lang)
selectedLanguage = lang
return i18n.setLocaleMessage(selectedLanguage, messages[lang])
}
App.vue
async beforeCreate () {
await loadLanguage(this.$userConfig.defaultLocalizationKey)
this.$i18n.locale = this.$userConfig.defaultLocalizationKey
}
The good practice is to always have a default/fallback language inside vue-i18n, e.g. English. If you can't do this for whatever reason, then you can simply put a v-if on the App's template so that nothing is rendered until you fetch at least 1 language into vue-i18n.
I met problem with date and currency interpoation in my app. I tried to find out some workaround but I could not for my case.
My app works this way: It initialized with en-US locale. After user login data comes where one field is User's Region. This one is setted in local. For this purpose I do:
// app.module
providers: [
...
{
provide: LOCALE_ID,
deps: [LocaleService],
useFactory: localeProviderFactory
}
...]
export function localeProviderFactory(provider: LocaleService) {
return provider.getCurrent();
}
//my service
export class LocaleService {
locale: BehaviorSubject<any>;
constructor() {
this.locale = new BehaviorSubject<GroupModel> (this.getGroupFromLocalStorage());
}
private getGroupFromLocalStorage(): GroupModel {
let parse = JSON.parse(localStorage.getItem('currentUser'));
return parse ? parse.Region : 'en-US';
}
setLocale(val) {
this.locale.next(val);
}
getCurrent() {
return this.locale.getValue();
}
}
So after user login I call setLocale() in LocaleService and pass there new User Region.
Problem is that I don't know which region will be setted and i don't want import all locales into app. Angular 5 require all locales imported before app starts. With:
import { registerLocaleData } from '#angular/common';
import localeFr from '#angular/common/locales/fr';
registerLocaleData(localeFr);
Is it possible to import/load and register locales dynamicaly in run time? Or is there some workarounds?
No, unfortunately it's not possible. As Rob McCabe in his answer to his own question here said:
Angular only works with one language at a time, you have to completely reload the application to change the lang. The JIT support only means that it works with JIT, but you still have to provide the translations at bootstrap because it will replace the text in your templates during the compilation whereas this lib uses bindings, which means that you can change the translations at any time.
I'm using react-i18next in my reactjs app.
Problem is when I change the language the app reloads and always starts from main route.
is there a way to redirect on same page or change language without reload page?
thanks
UPDATE
I18n.js
import i18n from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import {de} from "../../locales/de";
import {en} from "../../locales/en";
i18n
.use(LanguageDetector)
.init({
resources: {
en: en,
de: de
},
fallbackLng: 'de',
// have a common namespace used around the full app
ns: ['translations'],
defaultNS: 'translations',
keySeparator: '.',
interpolation: {
escapeValue: false, // not needed for react!!
formatSeparator: ','
},
react: {
wait: true
}
});
export default i18n;
Change Language:
const { t, i18n } = this.props;
const changeLanguage = (lng) => {
i18n.changeLanguage(lng);
};
how do you change language? using querystring?
if you call i18next.changeLanguage(lng); there won't be a change, just rerender in new language...
as a sample see: https://github.com/i18next/react-i18next/blob/master/example/webpack2/app/components/View.js#L50
Had the same issue. I was using i18n-js and react navigation to manifest stacks and tabs. This thread was the only one I could find on the internet. However, it did not lead me to the solution. Anyway, I still managed to sort it out and would share my solution.
Check if you also translate the names of your stacks and tabs, most likely it should be the tab one. The translated name will make react navigation lost as it no longer recognize the pages being recorded in the route, as the tab names are completely new in another language. That is why it jumps to the page wherever it finds it is the top of all navigators. The walkaround is to use label for the texts you want to translate and display while keeping a static name for your pages.