vue3 i18n lazy loading not loading text

Viewed 510

I have installed i18n in vue 3 https://vue-i18n.intlify.dev/introduction.html and I want to load the json files lazy.

In the app.js

const i18n = createI18n({
   legacy: false,
   globalInjection: true,
   locale: 'en',
   fallbackLocale: 'en'
})

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

In the main component I have a select

<select class="form-control" @change="onChangeLocale" v-model="selectedLocale">
    <option v-for="locale in availableLocales" :key=`locale-${locale}` :value="locale" v-text="locale.toUpperCase()">
</select>

and a text

{{ $t("hello_world") }}

which is in every files in locales (en.json, ro.json, de.json)

ex for en.json

{
    "hello_world": "Hello World"
}

In setup

setup() {
    const {t, locale, i18n} = useI18n({useScope: 'global'})
    const selectedLocale = ref(locale.value)
    const availableLocales = ref(['en', 'ro', 'de'])
    
    const onChangeLocale = async () => {
        const messages = await import(
        /* webpackChunkName: "locale-[request]" */ `../../locales/${selectedLocale.value}.json`
    )

    // set locale and locale message
    i18n.setLocaleMessage(selectedLocale.value, messages.default)
    }
}

When loadin the app i see the key for the text "hello_world" - with the message in console (not found "hello_world" key in "en" locale messages) and when changing the select for another language I get en error - cannot read property of undefined (reading 'setLocaleMessage)'

Any idea what I did wrong ?

If setting the messages in app.js like this:

const messages = {
    en: {
        hello_world: 'Hello World'
    },
    de: {
        ...
    }
}

then set the messages in i18n options it works.

But I want to load the json files with the translations when selecting the language

https://vue-i18n.intlify.dev/guide/advanced/lazy.html

Any idea ?

*** UPDATE ***

It seems to work after making some changes:

  1. load default language en.json in app.js
import enLocaleMessages from './locales/en.json'

const i18n = createI18n({
   legacy: false,
   globalInjection: true,
   locale: 'en',
   fallbackLocale: 'en',
   messages: {en: enLocaleMessages} // the new change
})
  1. in the component where the locale changes
const {t, locale, setLocaleMessage} = useI18n({useScope: 'global'})

const onChangeLocale = async () => {
    const messages = await import(
        /* webpackChunkName: "locale-[request]" */ `../../locales/${selectedLocale.value}.json`
    )
    
  setLocaleMessage(selectedLocale.value, messages.default)
  locale.value = selectedLocale.value
  document.documentElement.lang = selectedLocale.value
  axios.defaults.headers.common['Accept-Language'] = locale.value
}

I am not sure if it's the correct way ....but for the moment works.

0 Answers
Related