Hello,
It unclear to me from the docs if using setLocaleMessage() is how you get dynamic locales at runtime to work. There are many articles about how to do that at build time, but none that I could see about runtime changes.
To give an example, here is what I mean in the form of a timeline:
setLocaleMessage() as shown below:const i18n = new VueI18n({...});
...
i18n.setLocaleMessage('en', {...pathsHere});
...
//Later on:
//After another AJAX call to fetch fr.json:
i18n.setLocaleMessage('fr', {...pathsHere});
This works for me locale_switcher.vue:
<template>
<div class="locale-switcher">
<!-- {{ initLocale() }} -->
<b-nav-item-dropdown :dropup="dropup" :text="dropdownLbl" right>
<b-dropdown-item
class="locale-link"
v-for="locale in locales"
:key="locale.id"
@click="setLocale(locale)"
:class="{ 'is-current': locale === activeLocale }"
href="#">
{{ getLanguageString(locale) }}
</b-dropdown-item>
</b-nav-item-dropdown>
</div>
</template>
<script>
import Vue from 'vue'
// Restore locale from cookie, if it was set
import VueCookie from 'vue-cookie'
Vue.use(VueCookie)
const localeStrings = {
en: "English",
nl: "Nederlands",
ru: "Russian",
ua: "Ukrainian",
fr: "Fran莽ais",
de: "Deutsch"
}
Vue.config.lang = VueCookie.get('locale') || 'en'
console.log("Locale from cookie = " + Vue.config.lang + ": language = " + localeStrings[Vue.config.lang])
export default {
props: {
locales: {
type: Array,
default: ['en']
},
showFull: Boolean,
dropup: Boolean,
locLabel: {
type: String,
default: ''
}
},
data: function () {
return {
activeLocale: Vue.config.lang
}
},
computed: {
dropdownLbl: function () {
return this.locLabel ? this.locLabel : this.activeLocale
}
},
methods: {
setLocale: function (locale) {
Vue.config.lang = locale
this.activeLocale = locale
this.$cookie.set('locale', locale)
this.$i18n.locale = Vue.config.lang
console.log("New locale = " + Vue.config.lang + ": language = " + localeStrings[Vue.config.lang])
},
getLanguageString: function (locale) {
return this.showFull ? localeStrings[locale] : locale
}
}
}
</script>
And as component:
```html
````
Here is my solution:
app.i18n = new VueI18n({
locale: 'es',
fallbackLocale: 'es',
messages
})
Object.defineProperty(Vue.prototype, '$locale', {
get: function () {
return app.i18n.locale
},
set: function (locale) {
app.i18n.locale = locale
}
})
// this part happens later
new Vue(app)
Usage:
this.$locale // root Vuei18n locale
this.$locale = 'en' // set root Vuei18n locale
Edit: this works too:
this.$root.i18n.locale // root Vuei18n locale
this.$root.i18n.locale = 'en' // set root Vuei18n locale
@BenoitRanque that solution is very nice, thanks!
@BenoitRanque So easy compared to other solutions I've seen ! Thanks a lot.
just a quick one.. this.$root.i18n.locale didn't work... this works this.$locale.
@kazupon Why do you think this issue is solved?
Personally, I could work this issue around like this:
// change global locale like this in any component:
this.$root.$i18n.locale = 'newLocale';
// then, use the global locale like this in any (other or the same) component:
this.$t(
somePath, // example: 'hello {name}'
this.$root.$i18n.locale,
namedFormattingParametersObject, // optional. example: { name: 'kazupon' }
);
IMHO you can find the best (but still bad) documentation regarding this here: https://kazupon.github.io/vue-i18n/en/migrations.html#instance-properties @kazupon Do I see correctly that $i18n isn't documented anywhere else than there?
There should be some easy way to change the global language/locale at run-time / dynamically and it should be documented very well and at a central point because this IMHO is an essential feature of this type of library.
+1
+1
+1
Place it in a store?
I don't like to use this.$root in general so my solution since I'm using vuex was this:
On i18n.js I use a dynamic locale value from a state getter with a fallback as well.
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import store from '@/store.js'
Vue.use(VueI18n)
export default new VueI18n({
locale: store.getters.getLangKey || 'en',
messages: loadLocaleMessages()
})
This works perfectly for me. You just have to access to the i18n object directly and change its params there.
this.$root._i18n._vm.locale
Also, @DMouroutis, how could you manage to get the value from the store dinamically? Using vuex was my first option and I implemented it as you did, but can't manage to retreive the data after mutating them.
Most helpful comment
There should be some easy way to change the global language/locale at run-time / dynamically and it should be documented very well and at a central point because this IMHO is an essential feature of this type of library.