Search code examples
vue.jsinternationalizationvuejs3vue-i18n

How to use JSON files with createI18n in Vue


If I have a Vue project with a main.js file that looks like this:

import { createI18n } from "vue-i18n";
import { createApp } from 'vue'
import './styles/main.scss'
import App from './App.vue'

const i18n = createI18n({
  locale: 'en', // set locale
  fallbackLocale: 'en',   
  legacy: false,
  globalInjection: true,
  messages: {
    en: {
    sample:{
      item1: 'hello world'
    }
  }} // set locale messages
});

const app = createApp(App)

app.use(i18n)
app.mount('#app')

How can I edit this so that the messages object uses my JSON translation files? Basically, I have translation files in my locale folder, and some examples are en-US.json and fr-FR.json.

So instead of hardcoding the transaltions directly inside of the messages object, I'd like to use my locale folder. Is this possible?


Solution

  • I finally got it. The below code will load locale files from whatever path you specify in the loadPath option and uses the new i18next-http-backend since the i18next-xhr-backend was deprecated. And this code will auto detect the language and switch to the correct language if you locale file names have a structure like this: en-US.json, en-PH.json, es-MX.json, etc.

    import i18next from 'i18next'
    import I18NextVue from 'i18next-vue'
    import LanguageDetector from 'i18next-browser-languagedetector'
    import i18nextHttpBackend from 'i18next-http-backend'
    
    i18next.use(i18nextHttpBackend).use(LanguageDetector)
      .init({
        detection: {
          caches: false
        },
        fallbackLng: {
          default: ['en-US']
        },
        whitelist: [
          'en',
          'en-PH',
          'en-US',
          'es-MX'],
        backend: {
          loadPath: 'src/locales/{{lng}}.json'
        },
        load: 'currentOnly',
        interpolation: { escapeValue: false },
        saveMissing: true,
        saveMissingTo: 'all'
      });
    
    export default function (app) {
      app.use(I18NextVue, { i18next })
      return app
    }
    

    And then use it by having this code in your main.js:

    const app = createApp(App)
    i18next(app)
    app.mount('#app')