grif
grif

Reputation: 31

Vue3 - vue-cli-plugin-i18n - Can't change language dynamically

I am actually trying to follow this video tutorial : https://www.youtube.com/watch?v=CFGjn3yKMNc

Summary of the problem : I can't change the language dynamically with i18n. It stays on the language i18n was initialised with.

So, my i18n uses a different json file for each languages :

locales/en.json containing : { "message" : "hello world"}

locales/fr.json containing : { "message" : "bonjour"}

In the i18n.js (below) files, if I change locale value to en, "hello world" is displayed, and if I put fr instead of en, "bonjour" is displayed. Works Ok.

This code is what came with the installation of i18n except for the .default

function loadLocaleMessages() {
    const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i)
    const messages = {}
    locales.keys().forEach(key => {
        const matched = key.match(/([A-Za-z0-9-_]+)\./i)
        if (matched && matched.length > 1) {
            const locale = matched[1]
            messages[locale] = locales(key).default

        }
    })
    console.log(messages)
    return messages
}

export default createI18n({
    legacy: false,
    globalInjection: true,
    locale: 'fr',
    fallbackLocale: 'fr',
    messages: loadLocaleMessages()
})

The default language is fr Now, in my main.js, I have the code below. The goal is to pass a lang parameter in the URL. This work, I get the param. Unfortunately, even if the param is set to 'en', bonjour is still displayed. I tried to force it by replacing i18n.locale = language with i18n.locale = 'en', no luck. In fact, in the console, even if the i18n.locale value is set to 'en', it still displays french.

However, like I said, if I replace the locale: 'fr', in the code above with locale: 'en', it works...

router.beforeEach((to, from, next) => {

    let language = to.params.lang;
    if (!language) {
        language = 'en'
    }
    i18n.locale = language
    console.log("Active locale: ", i18n.locale)
    next()
})


const app = createApp(App)
app.use(router)
app.use(i18n)
app.mount('#app')

Does Anybody has a clue of why it is not working although the i18n.locale value is changed to 'en' ?

Thank you for your time :)

My version of i18n and vue are

"vue": "^3.0.0",
"vue-i18n": "^9.1.6"
"@intlify/vue-i18n-loader": "^2.1.0",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.0",
"vue-cli-plugin-i18n": "~2.1.1"

Upvotes: 3

Views: 1094

Answers (1)

Renaud
Renaud

Reputation: 79

I had the same problem and solved by changing the router.beforeEach(...) to:

router.beforeEach((to, from, next) => {
    let language = to.params.lang

    if (!language) {
    language = 'fr'
    }

    i18n.global.locale.value = language
    next()
})

Upvotes: 0

Related Questions